【问题标题】:NullReferenceException in System.Web calling ServiceStack service with GetAsync from async ServiceStack serviceSystem.Web 中的 NullReferenceException 使用来自异步 ServiceStack 服务的 GetAsync 调用 ServiceStack 服务
【发布时间】:2017-05-25 17:06:40
【问题描述】:

我有一个从上到下使用异步的 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 没有问题,您为什么不使用它?也不需要为每个请求创建一个新的 ServiceClient 实例(即你可以只使用一个单例实例),也不需要释放它。
  • @mythz JsonHttpClient 似乎已经解决了这个问题。 JsonServiceClient 是否存在固有问题?主要区别是什么?
  • @hedjos JsonServiceClient 基于 .NET 的 HttpWebRequest 而 JsonHttpClient 基于 Microsoft 的 HttpClient。但是这个 NRE 发生在 ASP.NET 中,而不是服务客户端。这会导致任何服务异常吗?如果是这样,请使用服务异常的完整 StackTrace 更新问题。
  • @mythz 我在帖子中添加了完整的服务器堆栈跟踪。没有服务异常被抛出回客户端。最终,客户端收到一个异常,指示“任务已取消”。这似乎只发生在从客户端向服务发出 2 个或更多并发请求时。
  • @hedjos 我特别关注服务异常,我们无法控制内部 ASP.NET 异常,也没有告诉我们异常的来源。如果您可以组装一个我们可以在本地运行的独立重现(例如在 GitHub 上),我们可以看看。

标签: c# asynchronous servicestack nullreferenceexception


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多