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
或其他地方进行此设置,在那里你可以本地异步到顶部.
我想出了我的问题,它是双重的。
我的库在启动时失败是库中的一个错误导致了一个没有冒泡的异常。我能够减轻这个错误。使用内部带有 .Result
的 MVC 应用程序启动时的异步调用似乎实际上没有问题。
我的 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;
}
我有一个用于音频文件处理的异步库。此外,我想通过 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
或其他地方进行此设置,在那里你可以本地异步到顶部.
我想出了我的问题,它是双重的。
我的库在启动时失败是库中的一个错误导致了一个没有冒泡的异常。我能够减轻这个错误。使用内部带有
.Result
的 MVC 应用程序启动时的异步调用似乎实际上没有问题。我的 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;
}