【问题标题】:Correct Way to use an async Library with ASP.NET/MVC/REST在 ASP.NET/MVC/REST 中使用异步库的正确方法
【发布时间】:2020-02-01 10:54:15
【问题描述】:

我有一个用于音频文件处理的异步库。此外,我想通过 Rest 提供这些方法。所以我做了一个 MVC WebApi 项目。库需要一些时间来启动,所以我添加了一个类,它提供了一种初始化方法并公开了库主对象。

public static class MusicHandler
{
    public static MusicCapture.MusicCapture MusicCapture;
    public static void init()
    {
        MusicCapture = new MusicCapture.MusicCapture("D:\\Temp", "D:\\test", "E:\\FingerPrintDB2.ss");
        MusicCapture.Start();
    }
}

我在 Application_Start() 中启动它

protected void Application_Start()
{
    MusicHandler.init();
}

现在当我的 init 方法包含一些像这样的异步调用时:

var hashedFingerprints = command.Hash().Result;

程序将跳过这些行。据我所知,他们并没有被处决。 当我从 REST 端点调用任何对象异步方法时,也会发生同样的事情。当我不是从 ASP.NET/MVC 运行库时,代码可以完美运行。

我发现一些 cmets 说这是由于死锁而导致的问题,但没有建议或代码如何避免这种情况/使其工作。

提前谢谢你。

【问题讨论】:

  • 永远不要使用'.Result' 你应该'await command.Hash()'
  • @IeuanW 但是我必须使这个方法异步,一直到顶部,但是 Application_Start() 不是异步的。
  • 如果你使用 DI,你不需要在启动时添加任何东西。即,如果您使用单例,那么整个类将准备就绪并等待其他调用者使用。

标签: c# asp.net asynchronous async-await audio-fingerprinting


【解决方案1】:

所以,如果我理解的话,您想启动一个名为 MusicHandler 的东西,这需要一点时间才能启动。 加载完成后,将通过 RESTful HTTP 调用与您的系统进行通信。

在您的 MusicHandler 中,您可以有一个标志来说明它是否已完成加载。

public static class MusicHandler
{
    public static MusicCapture.MusicCapture MusicCapture;
    public static bool Initialized {get;} = False;
    public static void init()
    {
        MusicCapture = new MusicCapture.MusicCapture("D:\\Temp", "D:\\test", "E:\\FingerPrintDB2.ss");
        MusicCapture.Start();
        Initialized = true;
    }
}

然后在您的 MVC 控制器中,您可以检查此标志并在初始化尚未完成时返回错误。

这样你就不用担心被async 一路顶到了。

但我很惊讶您竟然使用了application_start...使用 kestrel 托管它并在 program.cs 或其他地方进行此设置,您可以在本地与顶部异步。

【讨论】:

    【解决方案2】:

    我发现了我的问题,它是双重的。

    1. 我的库在启动时失败是库中的一个错误,它导致了一个没有冒泡的异常。我能够减轻这个错误。使用内部带有 .Result 的 MVC 应用程序启动时的异步调用似乎实际上没有问题。

    2. 我的 REST 调用异步失败可以通过将 REST 控制器方法更改为异步来修复。我从没想过这是可能的,但我在这里找到了一个例子:https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

    // GET api/music
    public async System.Threading.Tasks.Task<string> GetAsync()
    {
        string result = await MusicHandler.MusicCapture.DetectAsync(5);
        Console.WriteLine("Server returning: " + result);
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-07
      • 2012-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-09
      • 1970-01-01
      • 2015-05-31
      相关资源
      最近更新 更多