C#HttpClient PostAsync等待抛出NullReferenceException

时间:2018-09-17 19:25:21

标签: c# asp.net .net dotnet-httpclient

首先,我正在尝试为产品构建插件-因此环境不是我的,并且我对所发生的事情一无所知。据我所知,系统正在运行.NET Framework 4.6.2,并且我尝试确保所有依赖项都与系统上的内容匹配。

我看到的问题是,当我发出await PostAsync(...)请求时,我得到了NullReferenceException。这是100%可复制的。但是,如果我使用PostAsync(...).Result发出完全相同的请求,则一切正常。

鉴于我可以在解析响应时使用await关键字,这使我感到陌生,它仍然可以正常工作。

我想使用await关键字以“正确”的方式进行操作,但这只是行不通。从我一直阅读的所有内容来看,这可能是一个依赖问题,但是我不知道在哪里可以找到它。当我最终发现使用.Result'修复'我的问题时,我已经花了三天时间。

相关代码:

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()

2 个答案:

答案 0 :(得分:2)

我会尝试使用一些建议listed here

特别尝试在appSetting中添加以下web.config

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

以及httpRuntime中的以下system.web元素:

<system.Web>
    <httpRuntime targetFramework="4.5" />
</system.Web>

答案 1 :(得分:0)

由于托管插件的ASPX页面不是异步的,因此我无法在处理程序中使用异步方法。我最终不得不确保使用同步调用而不是异步调用。

要证明这一点,请添加行(马丁建议)

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

并使用await调用,我的插件在发出请求后开始挂起。

此SO页面:[Async Deadlock?] [1],向我暗示我的插件所在的页面未正确设置为异步功能。我尝试添加RegisterAsyncTask,然后在日志中看到一条新消息:

InvalidOperationException:此操作要求页面是异步的(Async属性必须设置为true)。