C# 使用async await会丢失http上下文吗?

C# 使用async await会丢失http上下文吗?,c#,asp.net,iis,async-await,C#,Asp.net,Iis,Async Await,有时,我们的应用程序会因为以下错误而崩溃:,我不想讨论此错误本身,但对可能的原因有一些疑问: 我用ILSpy查看了system.web中的代码,我得到的印象是http运行时会丢失上下文(和非托管指针),因此会崩溃。我没有关于异常的详细信息,所以我检查了所有的代码,除了一个api调用之外,一切都非常简单 大致如下所示(伪代码): 因此,在我看来,将其并行化以减少响应时间是有意义的。HttpContext存储在SynchronizationContext上。通过使用Task.Run卸载到线程池线程,

有时,我们的应用程序会因为以下错误而崩溃:,我不想讨论此错误本身,但对可能的原因有一些疑问:

我用ILSpy查看了system.web中的代码,我得到的印象是http运行时会丢失上下文(和非托管指针),因此会崩溃。我没有关于异常的详细信息,所以我检查了所有的代码,除了一个api调用之外,一切都非常简单

大致如下所示(伪代码):


因此,在我看来,将其并行化以减少响应时间是有意义的。

HttpContext存储在SynchronizationContext上。通过使用Task.Run卸载到线程池线程,您没有使用SC,因此无法访问HttpContext

如果
CallAsync
是一种异步方法,您实际上不需要使用Task。在此处运行,您只需存储返回的Task即可:

 tasks.Add(service.CallAsync(write);
如果仍需要Task.Run,则可以手动传递HttpContext:

var context = HttpContext.Current;
tasks.Add(Task.Run(() => 
{
    HttpContext.Current = context;
    service.CallAsync(write)
});

HttpContext存储在SynchronizationContext上。通过使用Task.Run卸载到线程池线程,您没有使用SC,因此无法访问HttpContext

如果
CallAsync
是一种异步方法,您实际上不需要使用Task。在此处运行,您只需存储返回的Task即可:

 tasks.Add(service.CallAsync(write);
如果仍需要Task.Run,则可以手动传递HttpContext:

var context = HttpContext.Current;
tasks.Add(Task.Run(() => 
{
    HttpContext.Current = context;
    service.CallAsync(write)
});


为什么方法是异步的?您只需创建一个委托并将其传递。另外,
StreamWriter
不是线程安全的,您正在从多个线程使用它。@i3arnon-最有可能的是真正的代码锁定了
writer
操作,以处理
StreamWriter
(可能是底层自定义流)不是线程安全的事实。很难理解您的意思“丢失”-显然是对
服务的调用。调用
将没有HttpContext可供启动,因此它不会发生故障(即使调用运行到请求结束之后),但您所展示的代码中没有其他地方对HttpContext有任何有趣的地方。@i3arnon:是的,streamwriter上有一个锁,我还在我的帖子中添加了原因,为什么方法是异步的,并对代码进行了一点编辑(服务可以是异步的)。为什么方法
是异步的呢?您只需创建一个委托并将其传递。而且,
StreamWriter
不是线程安全的,您正在从多个线程使用它。@i3arnon-最有可能的是真正的代码锁定了
writer
操作,以便只处理
StreamWriter
(可能是底层自定义流)不是线程安全的。很难理解“丢失”是什么意思-显然调用
服务。Call
将没有HttpContext可供启动,因此它不是可能发生故障的地方(即使调用在请求结束后运行),但您所展示的代码中没有其他地方对HttpContext有任何有趣的地方。@i3arnon:是的,streamwriter上有一个锁,我还在我的帖子中添加了原因,为什么方法是异步的,并对代码进行了一点编辑(服务可以是异步的)。是的,我知道“问题”“使用synchronizationcontext,不要访问内部的HttpContext。也许这个问题有点太模糊了。我只是在寻找这个讨厌的bug,并试图消除所有可能的问题。@SebastianStehle你是什么意思?如果您知道没有http上下文。你的问题是什么?一个例子可能是以下潜在问题:假设用户取消http请求,iis停止请求,那么http上下文就消失了。运行搜索的任务会发生什么情况?它们仍在运行,并尝试将结果写入流。现在发生了什么?我在这里从来没有例外,但这可能是个问题。例如,流仍然有效,搜索完成后,PushStreamContent尝试完成请求(由于accessviolationexception失败)。@SebastianStehle我认为IIS无法在请求完成之前停止请求。不管怎么说,这还不是个问题。你是对的,对不起。将关闭该问题,因为它不够具体。是的,我知道synchronizationcontext的“问题”,并且不访问其中的HttpContext。也许这个问题有点太模糊了。我只是在寻找这个讨厌的bug,并试图消除所有可能的问题。@SebastianStehle你是什么意思?如果您知道没有http上下文。你的问题是什么?一个例子可能是以下潜在问题:假设用户取消http请求,iis停止请求,那么http上下文就消失了。运行搜索的任务会发生什么情况?它们仍在运行,并尝试将结果写入流。现在发生了什么?我在这里从来没有例外,但这可能是个问题。例如,流仍然有效,搜索完成后,PushStreamContent尝试完成请求(由于accessviolationexception失败)。@SebastianStehle我认为IIS无法在请求完成之前停止请求。不管怎么说,这还不是个问题。你是对的,对不起。我将结束这个问题,因为它不够具体。