System.Web中的NullReferenceException使用异步ServiceStack服务

时间:2017-05-25 17:06:40

标签: c# asynchronous servicestack nullreferenceexception

我有一个从上到下使用async的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]

如果我用对System.Net.WebRequest之类的异步调用替换JsonServiceClient(以检索和淡化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的问题。任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

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