C# HttpClient.SendAsync 等待抛出 NullReferenceException
C# HttpClient.SendAsync await throws NullReferenceException
首先,我正在尝试为产品构建一个插件 - 所以环境不是我的,我对正在发生的事情没有太多的了解。据我所知,系统是 运行 .NET Framework 4.6.2,我已尝试确保我的所有依赖项与系统上的相匹配。
我遇到的问题是,当我发出 await PostAsync(...)
请求时,我收到 NullReferenceException
。这是 100% 可重现的。但是,如果我使用 PostAsync(...).Result
发出完全相同的请求,一切正常。
这很奇怪,因为我可以在响应的解析中使用 await
关键字,而且它仍然可以正常工作。
我想用 'right' 的方式,使用 await
关键字,但它不起作用。从我一直在阅读的所有内容来看,这可能是一个依赖性问题,但我不知道在哪里可以找到它。当我 终于 发现使用 .Result
'fixes' 我的问题时,我已经花了 3 天时间。
相关代码:
private async Task<T> aFunction<T>(string path, Dictionary<string, string> data) {
var content = new FormUrlEncodedContent(data);
var response = client.PostAsync(path, content).Result; // This works
// var response = await client.PostAsync(path, content); // This does not
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
var parsed = JsonConvert.DeserializeObject<T>(result);
return parsed;
}
NRE 的堆栈跟踪:
Stack trace:
at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.<>c.<ThrowAsyncIfNecessary>b__18_0(Object s)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
我会尝试使用一些建议 listed here。
特别尝试在 web.config
中添加以下 appSetting
:
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
以及 system.web
中的以下 httpRuntime
元素:
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
由于托管插件的 ASPX 页面不是异步的,因此我无法在我的处理程序中使用异步方法。我最终不得不确保使用同步调用而不是异步调用。
为了证明这一点,在添加行之后(Martin 推荐)
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
并且使用 await 调用,我的插件在发出请求后开始挂起。
这个 SO 页面:[Async Deadlock?][1],暗示我的插件所在的页面没有正确设置异步功能。我尝试添加 RegisterAsyncTask,并在日志中看到一条新消息:
InvalidOperationException: 此操作要求页面是异步的(Async 属性必须设置为 true)。
首先,我正在尝试为产品构建一个插件 - 所以环境不是我的,我对正在发生的事情没有太多的了解。据我所知,系统是 运行 .NET Framework 4.6.2,我已尝试确保我的所有依赖项与系统上的相匹配。
我遇到的问题是,当我发出 await PostAsync(...)
请求时,我收到 NullReferenceException
。这是 100% 可重现的。但是,如果我使用 PostAsync(...).Result
发出完全相同的请求,一切正常。
这很奇怪,因为我可以在响应的解析中使用 await
关键字,而且它仍然可以正常工作。
我想用 'right' 的方式,使用 await
关键字,但它不起作用。从我一直在阅读的所有内容来看,这可能是一个依赖性问题,但我不知道在哪里可以找到它。当我 终于 发现使用 .Result
'fixes' 我的问题时,我已经花了 3 天时间。
相关代码:
private async Task<T> aFunction<T>(string path, Dictionary<string, string> data) {
var content = new FormUrlEncodedContent(data);
var response = client.PostAsync(path, content).Result; // This works
// var response = await client.PostAsync(path, content); // This does not
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
var parsed = JsonConvert.DeserializeObject<T>(result);
return parsed;
}
NRE 的堆栈跟踪:
Stack trace:
at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.<>c.<ThrowAsyncIfNecessary>b__18_0(Object s)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
我会尝试使用一些建议 listed here。
特别尝试在 web.config
中添加以下 appSetting
:
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
以及 system.web
中的以下 httpRuntime
元素:
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
由于托管插件的 ASPX 页面不是异步的,因此我无法在我的处理程序中使用异步方法。我最终不得不确保使用同步调用而不是异步调用。
为了证明这一点,在添加行之后(Martin 推荐)
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
并且使用 await 调用,我的插件在发出请求后开始挂起。
这个 SO 页面:[Async Deadlock?][1],暗示我的插件所在的页面没有正确设置异步功能。我尝试添加 RegisterAsyncTask,并在日志中看到一条新消息:
InvalidOperationException: 此操作要求页面是异步的(Async 属性必须设置为 true)。