System.Web 从异步 ServiceStack 服务使用 GetAsync 调用 ServiceStack 服务时出现 NullReferenceException

NullReferenceException in System.Web calling ServiceStack service with GetAsync from async ServiceStack service

我有一个从上到下使用异步的 ServiceStack 服务。下面是一个简化的示例,所有层都折叠到服务定义。

public async Task<ReadItemResponse> Get(Dto.ReadItem request)
{
    using (JsonServiceClient client = new JsonServiceClient("http://someserver/itemservice"))
    {
        ReadItemResponse response = await client.GetAsync(new ReadItem
        {
            ItemNumber = request.ItemNumber
        });

        return new Dto.ReadItemResponse
        {
            Item = new Dto.Item
            {
                ItemNumber = response.Item.ItemNumber,
                ItemName = response.Item.ItemName
            }
        };
    }
}

当我对服务进行大量并发调用时,上述代码会在 1 - 30 秒内在 System.Web 中引发 NullReferenceException。

System.Web.dll!System.Web.ThreadContext.AssociateWithCurrentThread(bool setImpersonationContext)
System.Web.dll!System.Web.HttpApplication.OnThreadEnterPrivate(bool setImpersonationContext)
System.Web.dll!System.Web.HttpApplication.System.Web.Util.ISyncContext.Enter()
System.Web.dll!System.Web.Util.SynchronizationHelper.SafeWrapCallback(System.Action action = {Method = {System.Reflection.RuntimeMethodInfo}})
System.Web.dll!System.Web.Util.SynchronizationHelper.QueueAsynchronous.AnonymousMethod__0(System.Threading.Tasks.Task _)
mscorlib.dll!System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
mscorlib.dll!System.Threading.Tasks.Task.Execute()
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot = Id = 1131, Status = Running, Method = "Void <QueueAsynchronous>b__0(System.Threading.Tasks.Task)")
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution)
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
[Native to Managed Transition]

如果我将 JsonServiceClient 替换为对 System.Net.WebRequest 之类的异步调用(以检索和淡化 JSON 响应),我永远不会看到异常。

我试过 JsvServiceClient 也有同样的结果。我尝试使用 ConfigureAwait(false) 但没有成功。我已确保 web.config 文件正在调用:

<compilation targetFramework="4.5.2" debug="true" />
<httpRuntime targetFramework="4.5" />

我已经用以下代码包装了 Get 方法的主体:

await Task.Factory.StartNew(() =>

这解决了问题,但大大降低了服务的性能。吞吐量从能够在 2-3 秒内处理 100 个并发请求变为接近 20-40 秒。

我还能够在不遇到 NullReferenceException 的情况下进行异步数据库调用。

这绝对是 ServiceClient 的问题。任何帮助将不胜感激。谢谢!

使用 JsonHttpClient 代替 JsonServiceClient 解决了这个问题。