Seb*_*hle 1 c# asp.net iis async-await
我们的应用程序不时因为这个错误而崩溃:https://serverfault.com/questions/675649/accessviolationexception-iis ,我不想自己讨论这个错误,但对可能的原因有一些疑问:
我查看了使用ILSpy的system.web中的代码,我得到的结论是http运行时丢失了上下文(和一个非托管指针),因此崩溃了.我没有关于异常的详细信息所以我检查了所有代码,除了一个api调用之外,一切都非常直接.
它或多或少看起来像这样(伪代码):
private async Task SearchAsync()
{
Func<Stream, HttpContent, TransportContext, Task> searching =
async (stream, content, transportContext) =>
{
StreamWriter writer = new StreamWriter(stream);
Action<Data> write = new Action<Data>()
{
writer.WriteData(data);
writer.WriteLine();
writer.Flush();
};
List<Task> tasks = new List<Task>();
foreach (IService service in services)
{
tasks.Add(Task.Run(() => service.CallAsync(write));
};
await Task.WhenAny(
Task.Delay(10000),
Task.WhenAll(tasks));
};
response.Content = new PushStreamContent(searching, "text/event-stream");
}
Run Code Online (Sandbox Code Playgroud)
它看起来有点奇怪,但原因如下:
所以问题是:在这段代码中,http上下文能否以某种方式丢失?丢失意味着以下内容:在链接的问题中,您看到system.web中的本地方法失败.可能是因为传递给此方法的IntPtr(来自http上下文)不再有效
我看不到任何潜在的问题吗?如何正确处理IIS中的并行任务?
编辑:为什么service.CallAsync异步?
该代码简化了实际情况.在我的代码中,服务是真实服务的包装器.每个服务都有多个步骤,很多类和多个级别的调解器,但结构如下:
GetFromDatabase(); // Not async yet, because of mongo driver.
await CallServiceAsync(); // Sometimes async, sometimes not, depending on service.
PrepareResults(); // Not async, but cpu intensive.
Run Code Online (Sandbox Code Playgroud)
所以在我看来,将它并行化以减少响应时间是有道理的.
HttpContext存储在SynchronizationContext中.通过使用Task.Run卸载到ThreadPool线程,您没有使用SC,因此您无权访问HttpContext.
如果CallAsync是异步方法,您实际上不需要在这里使用Task.Run,而只需存储返回的任务:
tasks.Add(service.CallAsync(write);
Run Code Online (Sandbox Code Playgroud)
如果仍然需要Task.Run,您可以手动传递HttpContext:
var context = HttpContext.Current;
tasks.Add(Task.Run(() =>
{
HttpContext.Current = context;
service.CallAsync(write)
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1461 次 |
| 最近记录: |