2017-05-25 73 views
0

我有一個ServiceStack服務,從上到下使用異步。下面是一個簡化的例子,所有圖層都摺疊到服務定義。System.Web中的NullReferenceException從異步ServiceStack服務調用ServiceStack服務與GetAsync

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的問題。任何幫助將不勝感激。謝謝!

+2

可能重複[什麼是NullReferenceException,以及如何解決它?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-doi-i-fix -it) –

+0

如果'JsonHttpClient'沒有問題,爲什麼不使用它?也沒有必要爲每個請求創建一個新的ServiceClient實例(即,您可以使用單例實例),並且不需要處理它。 – mythz

+0

@аPlease請先閱讀帖子,然後將其盲目標記爲副本。謝謝。 – hedjos

回答

0

使用JsonHttpClient代替JsonServiceClient修復了這個問題。