简体   繁体   English

.net 4.5中的msmq未处理的异步异常

[英]msmq unhandled async exception in .net 4.5

I've done some prototypes with MSMQ and faced weird behavior. 我已经使用MSMQ完成了一些原型,并且遇到了奇怪的行为。

I have MSMQ service that sends data to some web service when there are messages incoming into queue. 我有MSMQ服务,当有消息进入队列时,该服务会将数据发送到某些Web服务。 I'm turning off web service and expecting to see System.ServiceModel.ServerTooBusyException so that my messages would be returned to queue and will be sent later. 我正在关闭Web服务,并希望看到System.ServiceModel.ServerTooBusyException以便我的消息将返回队列并稍后发送。 I'm hosting MSMQ service in console application. 我在控制台应用程序中托管MSMQ服务。

Now, if I'm sending data to web service synchronously then I get expected behavior. 现在,如果我正在将数据同步发送到Web服务,则会得到预期的行为。 If I send data asynchronously my console application crashes with unhandled exceptions System.ServiceModel.ServerTooBusyException . 如果我异步发送数据,则控制台应用程序会因未处理的异常System.ServiceModel.ServerTooBusyException崩溃。

Here is pseudo code: 这是伪代码:

Console 安慰

AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;

using (MSMQServiceHost serviceHost = new MSMQServiceHost(typeof(Service1)))
{
    serviceHost.Open();

     Console.WriteLine("Press any key to stop service...");
     Console.ReadKey(true);
}

private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
   MSMQ.Utils.LoggerHelper.GetLogger().ErrorFormat("CurrentDomainOnUnhandledException. {0}", unhandledExceptionEventArgs);
}

Service 服务

[OperationBehavior(TransactionScopeRequired = true)]
public async  void GetData(int start, int end)
{
    try
    {
      using (WebServiceReference.Service1Client webClient = new WebServiceReference.Service1Client())
      {
        string data = await webClient.GetDataAsync(start);
        //string data = webClient.GetData(start);
        MSMQ.Utils.LoggerHelper.GetLogger().InfoFormat("Received info from web service. Data\t{0}", data);
    }
}
catch (Exception e)
{
    MSMQ.Utils.LoggerHelper.GetLogger().ErrorFormat("{1}\r\n{0}", e.Message, e.GetType().FullName);
    throw;
}

} }

In case of synchronous call I get big list of logged errors, but application is not crashed. 在进行同步调用的情况下,我会得到大量记录的错误列表,但应用程序不会崩溃。 In case of asynchronous call I get the same list of logged errors plus the same number of CurrentDomainOnUnhandledException's (System.ServiceModel.ServerTooBusyException) 在异步调用的情况下,我将获得相同的记录错误列表以及相同数量的CurrentDomainOnUnhandledException(System.ServiceModel.ServerTooBusyException)

mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.ThrowAsync.AnonymousMethod__5(object state) Unknown mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Unknown mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unknown mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.ThrowAsync.AnonymousMethod__5(对象状态)未知mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext执行上下文,System.Threading.ContextCallback回调,对象状态,布尔prepareSyncCtx)未知mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext执行上下文,System.Threading.ContextCallback回调,对象状态,布尔状态,保持状态),SyncorCtx未知mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading。 IThreadPoolWorkItem.ExecuteWorkItem()未知mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()未知

My awaitable is observable - I've subscribed to TaskScheduler.UnobservedTaskException and nothing there. 我的等待是可观察的-我已经订阅了TaskScheduler.UnobservedTaskException,那里什么也没有。 How to properly use async in that case, so that I get all the benefits from APM and my application wouldn't crash? 在这种情况下,如何正确使用异步,这样我才能从APM获得所有好处,并且我的应用程序不会崩溃?

I got it. 我知道了。

The problem is with async modifier in my service operation. 问题出在我的服务操作中有async修饰符。 Correct version: 正确版本:

[OperationBehavior(TransactionScopeRequired = true)]
public async Task GetData(int start, int end)
{
    try
    {
        await Task.Factory.StartNew(() =>
        {
            using (WebServiceReference.Service1Client webClient = new WebServiceReference.Service1Client())
            {
                 Task<string> data = GetWebClientData(start, webClient);
                 MSMQ.Utils.LoggerHelper.GetLogger().InfoFormat("Received info from web service. Data\t{0}", data.Result);
            }
        }
  }
  catch (Exception e)
  {
      MSMQ.Utils.LoggerHelper.GetLogger().ErrorFormat("{1}\r\n{0}", e.Message, e.GetType().FullName);
     throw;
  }
}

private static async Task<string> GetWebClientData(int start, WebServiceReference.Service1Client webClient)
{
    return await webClient.GetDataAsync(start);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM