【问题标题】:Part of the code is non-reachable after using c# await使用 c# await 后部分代码无法访问
【发布时间】:2012-08-01 07:23:57
【问题描述】:

我正在为一个网站编写视频转换工具。

接下来是逻辑

  • 用户上传文件
  • 系统为用户转换(当然用户在转换时不应等待)

我有一个代码:

public async void AddVideo(HotelVideosViewModel model)
        {
            var sourceFile = FileHandler.SaveFile(model.VideoFile);
            var fullFilePath = HttpContext.Current.Server.MapPath(sourceFile);

            await Task.Factory.StartNew(() => video.Convert(fullFilePath));

            model.FileLocation = sourceFile;
            model.IsConverted = true;
            this.Add<HotelVideos>(Mapper.Map<HotelVideosViewModel, HotelVideos>(model));
        }

这个开始编码:

await Task.Factory.StartNew(() => video.Convert(fullFilePath));

但是这之后的代码永远不会执行......有人有解决方案吗?

PS:在 video.Conver(...) 下有类似:

public bool Convert(string fileLocation)
{
// do staff
}

--- 更新 ---

刚刚得到了有趣的东西。如果我要将video.Convert(fullFilePath) 交换为 Thread.Sleep(2000) 一切都会开始工作。所以我认为问题出在第二种方法中。

所以我正在添加下一个文件代码(现在草稿):

using Softpae.Media;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class VideoConvertManager
    {
        private readonly Job2Convert jobConverter = new Job2Convert();

        private readonly MediaServer mediaServer = new MediaServer();

        public bool Convert(string fileLocation)
        {
            this.jobConverter.pszSrcFile = fileLocation;
            this.jobConverter.pszDstFile = fileLocation + ".mp4";
            this.jobConverter.pszDstFormat = "mp4";
            this.jobConverter.pszAudioCodec = null;
            this.jobConverter.pszVideoCodec = "h264";

            if (this.mediaServer.ConvertFile(this.jobConverter))
            {
                FileHandler.DeleteFile(fileLocation);
                return true;
            };

            FileHandler.DeleteFile(fileLocation);
            return false;
        }
    }   

【问题讨论】:

  • PPS。这是我第一次使用 async/await :)
  • await 在 convert 完成之前不会返回,convert 是否已经完成?
  • 致Frobzig:当然,检查。对 cshemby:是的,我做到了。
  • 什么叫 AddVideo?除了需要 void 返回类型的处理程序之外,您通常希望避免使用“async void”。

标签: c# asp.net-mvc-3 asynchronous async-await


【解决方案1】:

在完成 ASP.NET 请求之前,您需要使 AddVideo 返回 Taskawait 其结果。

更新:不要在异步 Task 上调用 Wait 或其他阻塞方法! This causes deadlock.

您可能会发现my async intro 很有帮助。

附: async 不会改变 HTTP 的工作方式。每个请求仍然只有一个响应。如果您希望最终用户(例如浏览器)不阻塞,那么您必须实现某种队列系统,浏览器可以在其中启动视频转换作业并收到其结果通知(例如,使用 SignalR)。 async 不会神奇地实现这一点 - 它只适用于单个请求/响应对的上下文。

【讨论】:

  • 您好,感谢您的回答。我试图将 AddVideo 作为一项任务 - 同样的故事。 PS。我更新了描述
  • @EvgeniyLabunskiy:你在awaiting 吗?
【解决方案2】:

添加 ConfigureAwait(false) 将防止继续在请求线程上被强制

【讨论】:

  • 在 ASP.NET 中,不使用ConfigureAwait(false) 意味着继续请求context。但这并不意味着它必须是启动请求的同一个线程,它也不应该导致这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多