We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

File Upload slow

Hi,

I think I have a problem with file upload performance. I am uploading a file size "300MB" over a local hosted machine,
from within the IDE, and this takes more than a couple of minutes to upload. I get the sense that something is wrong.

I am using the chunked transfer, and after Inspecting the with the browser I am seeing a "serial" save call which transfers the 
chunks in sequence.

I have played adjusting the chinks size but still each "chunk" call seems to correspond to an http request which then gets routed to
the controller that saves the chunk.

Is this normal? Also how can I report the transport rate in MB/s.

Here is the code:

{.cshtml}
@using Syncfusion.EJ2

@{
    var asyncSettings = new Syncfusion.EJ2.Inputs.UploaderAsyncSettings { SaveUrl = @Url.Content("~/Uploader/Save"), RemoveUrl = @Url.Content("~/Uploader/Remove"), ChunkSize = 500000 }; 
}


<div class="control_wrapper">
<ejs-uploader id="uploadFiles" removing="onFileRemove"
dropArea=".control_wrapper" asyncSettings="@asyncSettings" maxFileSize="1048576000" autoUpload="false"
chunkFailure="onBeforeFailure" pausing="onPausing" resuming="onResuming">
</ejs-uploader>                        
</div>


@section Scripts {
<script>

    var dropElement = document.getElementsByClassName('control-fluid')[0];

    var isInteraction = false;
    // to update flag variable value for automatic pause and resume
    function onPausing(args) {
        if (args.event !== null && !navigator.onLine) {
            isInteraction = true;
        }
        else {
            isInteraction = false;
        }
    }

    // to update flag variable value for automatic pause and resume
    function onResuming(args) {
        if (args.event !== null && !navigator.onLine) {
            isInteraction = true;
        }
        else {
            isInteraction = false;
        }
    }

    function onFileRemove(args) {
        args.postRawFile = true;
    }

    // to prevent triggering chunk-upload failure event and to pause uploading on network failure
    function onBeforeFailure(args) {
        args.cancel = !isInteraction;
        var uploadObj = document.getElementById('uploadFiles').ej2_instances[0];
        // interval to check network availability on every 500 milliseconds
        var clearTimeInterval = setInterval(function () {
            if (navigator.onLine && !ej.base.isNullOrUndefined(uploadObj.filesData[0]) && uploadObj.filesData[0].statusCode == 4) {
                uploadObj.resume(uploadObj.filesData);
                clearSetInterval();
            }
            else {
                if (!isInteraction && !ej.base.isNullOrUndefined(uploadObj.filesData[0]) && uploadObj.filesData[0].statusCode == 3) {
                    uploadObj.pause(uploadObj.filesData);
                }
            }
        }, 500);
        // clear Interval after when network is available.
        function clearSetInterval() {
            clearInterval(clearTimeInterval);
        }
    }</script>



````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````



{.cs}

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Http.Features;

namespace xyz.Controllers
{
    public class UploaderController : Controller
    {
        private IHostingEnvironment hostingEnv;

        public UploaderController(IHostingEnvironment env)
        {
            this.hostingEnv = env;
        }

        [AcceptVerbs("Post")]
        public IActionResult Save(IList<IFormFile> UploadFiles)
        {
            try
            {
                foreach (var file in UploadFiles)
                {
                    if (UploadFiles != null)
                    {
                        var filename = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
                        filename = hostingEnv.WebRootPath + $@"/temp/{filename}";
                        if (!System.IO.File.Exists(filename))
                        {
                            using (FileStream fs = System.IO.File.Create(filename))
                            {
                                file.CopyTo(fs);
                                fs.Flush();
                            }
                        }
                        else
                        {
                            Response.Clear();
                            Response.StatusCode = 204;
                            Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File already exists.";
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Response.Clear();
                Response.ContentType = "application/json; charset=utf-8";
                Response.StatusCode = 204;
                Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "No Content";
                Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message;
            }
            return Content("");
        }

        [AcceptVerbs("Post")]
        public IActionResult Remove(IList<IFormFile> UploadFiles)
        {
            try
            {
                foreach (var file in UploadFiles)
                {
                    var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
                    var filePath = Path.Combine(hostingEnv.WebRootPath);
                    var fileSavePath = filePath + "/temp/" + fileName;
                    if (System.IO.File.Exists(fileSavePath))
                    {
                        System.IO.File.Delete(fileSavePath);
                    }
                }
            }
            catch (Exception e)
            {
                Response.Clear();
                Response.StatusCode = 204;
                Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File removed failed";
                Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message;
            }
            return Content("");
        }

        public IActionResult DefaultFunctionalities()
        {
            return View();
        }
    }
}






1 Reply

VK Vinoth Kumar Sundara Moorthy Syncfusion Team July 5, 2019 12:32 PM UTC

Hi Wayne, 
 
Good day to you. 
 
Query 1: I am uploading a file size "300MB" over a local hosted machine, from within the IDE, and this takes more than a couple of minutes to upload 
 
We have checked your reported performance issue and we would like to let you know that in File Uploader, the ChunkSize type is in bytes. We found that you have mentioned ChunkSize as 50000 bytes which is equivalent to 0.5 MB. If you upload file more than 300MB then each request can be 0.5 Mb which is nearly 600 chunks and due to the more request to the server, the performance can be slow. So, we would suggest you increase the chuck size as like in the below code snippet. 
 
@{ 
var asyncSettings = new Syncfusion.EJ2.Inputs.UploaderAsyncSettings { SaveUrl = "https://localhost:44364/Home/Save", RemoveUrl = "https://localhost:44364/Home/Remove", ChunkSize = 10000000 }; 
} 
 
Query 2: I am using the chunked transfer, and after Inspecting the with the browser I am seeing a "serial" save call which transfers the chunks in sequence. 
 
If you have used chunk uploader, then if you have upload one file, each request will be send to server as a sequential manner. Meanwhile, if you upload more than one file, then each file’s chunk request will be sent to server as parallel manner based on the behavior of our File uploader. 
 
Query 3: Is this normal? Also, how can I report the transport rate in MB/s. 
 
You can measure the transfer rate.  We have calculated the bytes per second based on the uploader start time and current time in progress event as like in the below code snippet, 
 
[Index.cshtml] 
function onProgress(args) { 
    var loaded = args.e.loaded; 
    var total = args.e.total; 
    var seconds_elapsed = (new Date().getTime() - started_at.getTime()) / 1000; 
    var bytes_per_second = seconds_elapsed ? loaded / seconds_elapsed : 0; 
    var Kbytes_per_second = bytes_per_second / 1000; 
    instances.listParent.querySelector('[data-file-name="' + args.file.name + '"]').querySelector("#size").innerHTML = instances.bytesToSize(bytes_per_second) + '/sec'; 
} 
 
Sample link: 
 
Regards, 
Vinoth Kumar S 


Loader.
Up arrow icon