ASP.NET/MVC/REST 使用异步库的正确方法

Correct Way to use an async Library with ASP.NET/MVC/REST

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

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 时,代码可以完美运行。

我发现一些评论说这是死锁导致的问题,但没有建议或代码如何避免 this/make 这个问题。

提前致谢。

所以,据我了解,您想启动一个名为 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 控制器中,您可以检查此标志,如果初始化尚未完成,return 会出现错误。

这样你就不用担心 async 一直到顶峰了。

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

我想出了我的问题,它是双重的。

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

  2. 我的 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;
}