C# .net异常 解决异步返回上下文时, 发生空上下文问题

43 阅读1分钟

错误代码:

An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/7/ROOT

Process ID: 1808

Exception: System.NullReferenceException

Message: 未将对象引用设置到对象的实例。

StackTrace:    在 System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
   在 System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
   在 System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
   在 System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
   在 System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
   在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   在 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   在 System.Threading.ThreadPoolWorkQueue.Dispatch()

造成问题原因: 调用异步方法时没有等待异步返回, 但是异步返回默认会继续返回到上下文, 此时原上下文已结束, 故发生上下文为空的错误.

解决办法:

 public static async Task Test1()
 {
    await Task.Factory.StartNew(() =>
        // 一些异步代码....
     
    });
 }

 public static void Test2()
 {
    Test1().ConfigureAwait(false); // 执行异步不等候, 且不返回到上下文
    Test1().Wait(); // 等候异步返回
 }

相关文章

Task.ConfigureAwait 方法 (System.Threading.Tasks) | Microsoft Learn

关于 ASP.NET Web 应用中 async/await 注意问题_weixin_33720078的博客-CSDN博客

传统asp.net小心 async/await坑_weixin_30486037的博客-CSDN博客

死锁 (等待了同一上下文)
private static async Task TestAsync()
{
    await Task.Delay(1000);
    // 业务代码
}

public static void TestOne()
{
    var task = TestAsync();
    task.Wait();
}
// await Task.Delay(1000);
await Task.Delay(1000).ConfigureAwait(false);  // 解决死锁