Async / Await似乎阻止了其他调用

时间:2016-04-15 14:34:30

标签: c# async-await

我对整个异步/等待C#的部分感到陌生,而且我现在已经在墙上撞了近一整天了。

我正在将文件从我的网页上传到另一个应用。当他们收到这个文件时,他们将开始执行它包含的一些指令(这很好)。 但是,如果将文件发送到他们的服务器,我会调用另一个方法,这将返回执行的进度。

我面临的问题是GetProgress()方法只会在UploadFile()方法完成后返回,此时进度将始终为100%。

这些是我目前正在使用的方法:

public class FileUpload : IHttpHandler
    {
    public async void ProcessRequest(HttpContext context)
    {

        HttpPostedFile uploadedfile = context.Request.Files[0];

        string FileName = uploadedfile.FileName;
        string FileType = uploadedfile.ContentType;
        int FileSize = uploadedfile.ContentLength;

       await UploadFile(uploadedfile.InputStream);
        GetProgress();

    }

         public async Task<HttpResponseMessage> UploadFile(Stream stream1)
        {
            HttpResponseMessage task = null;
            try
            {
                _importOperationId = Guid.NewGuid().ToString();
                using (var fileStreamContent = new StreamContent(stream1))
                using (var client = new HttpClient())
                {
                    using (var formData = new MultipartFormDataContent())
                    {
                        client.Timeout = new TimeSpan(0, 1, 0, 0);
                        formData.Add(fileStreamContent, _importOperationId, _importOperationId + ".xml");
                        task = await client.PostAsync(systemDataServiceUrl + resource + _importOperationId, formData);
                    }
                }

            }
            catch (Exception exc)
            {
                Logging.AddErrorLogItem(exc, _importOperationId, "Import.aspx");
            }
            return task;
        }
}

和前端部分:

    <form id="file_upload" >

    <input id="fileupload" type="file" name="files[]" data-url="FileUpload.ashx" multiple>


    <script src="../Scripts/jquery.ui.widget.js"></script>
    <script src="../Scripts/jquery.iframe-transport.js"></script>
    <script src="../Scripts/jquery.fileupload.js"></script>
    <script type="text/javascript">
        /*global $ */
        $(function () {
            $('#fileupload').fileupload({
                dataType: 'json',
                done: function (e, data) {
                    $.each(data.result.files, function (index, file) {
                        $('<p/>').text(file.name).appendTo(document.body);
                    });
                }
            });
        });
    </script>

任何帮助将不胜感激,由于某些原因我似乎无法掌握async / await如何工作,即使我对AJAX很满意。

2 个答案:

答案 0 :(得分:3)

  

我面临的问题是GetProgress()方法只会在UploadFile()方法完成后返回,此时进度将始终为100%。

您可以在GetProgress工作时轻松致电UploadFile,而不是await立即执行任务:

var uploadFileTask = UploadFile(uploadedfile.InputStream);
GetProgress();
await uploadfileTask;

虽然我认为你不能做我想你想做的事。

  

我似乎无法掌握async / await如何工作,即使我对AJAX很满意

重要的一点是async doesn't change the HTTP protocol(正如我在博客中描述的那样)。每个请求仍然只有一个响应。实际上不可能将进度更新作为多个响应发送,然后将最终结果作为另一个响应发送。您可能最好使用支持独立消息的传输,例如SignalR。

答案 1 :(得分:2)

这是预期的。 await所做的是引发异步操作,然后暂停调用方法,直到操作完成。一旦它,它恢复调用方法。

听起来毫无意义?是的,但是这个想法是一个覆盖的框架在这​​一点上可以做其他事情。在ASP.NET MVC中,我们看到当您运行异步操作方法和await某些内容(如光盘操作)时,我们等待时该线程可以处理另一个请求,从而提高系统的并发可用性。 WPF中的异步事件处理程序可以调用异步I / O,它不会阻止主渲染线程并提高应用程序响应能力,而无需程序员编写显式线程代码。

这个想法是给出同步编程的幻觉,同时以易于使用的方式获得异步性的一些好处。如果你想要真正的显式并发,你必须开始使用并发工具,例如任务并行库(首先构建async / await)明确地说“关闭并执行此操作我继续“。