QueueClient.OnMessage 在辅助角色启动期间抛出 StackOverflowException

QueueClient.OnMessage throws StackOverflowException during Worker Role Start up

我正在尝试部署我的第一个 Azure 工作者角色,但在服务启动期间调用 运行() 方法时,我 运行 遇到了这个错误。

An unhandled exception of type 'System.WhosebugException' occurred in Unknown Module.

我尝试远程调试我的代码,但在这一行抛出了错误。 MyPublisher 类似于 MyQueue,但它包装了 Topic 而不是 Queue。知道为什么 QueueClient.OnMessage 会导致 Whosebug 吗?

Client.OnMessage(messageHandler, options);

这是部分代码。如果格式不正确(将尝试格式化)或代码中缺少任何内容,我深表歉意。

public class MyQueue
{
    String QueueName;
    public QueueClient Client { get; protected set; }

    public MyQueue(String queueName)
    {
        Trace.WriteLine($"Creating service Queue with name : {queueName} ");
        QueueName = queueName;
    }

    public void EstableshConnection(string connectionString = null)
    {
        Trace.WriteLine($"Establishing connection with service Queue : {QueueName} ");
        // Set the maximum number of concurrent connections 
        ServicePointManager.DefaultConnectionLimit = 12;

        connectionString = connectionString ?? CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
        NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
        if (!namespaceManager.QueueExists(QueueName))
            namespaceManager.CreateQueue(QueueName);

        Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
    }

    public void Send(BrokeredMessage message)
    {
        Trace.WriteLine($"Sending brokered message to queue : {QueueName} ");
        if (Client != null && !Client.IsClosed)
            Client.Send(message);
    }

    public void OnMessage(Action<BrokeredMessage> messageHandler)
    {
        Trace.WriteLine($"OnMessage handler: Queue Name : {QueueName} ");
        OnMessageOptions options = new OnMessageOptions();
        options.AutoComplete = true; // Indicates if the message-pump should call complete on messages after the callback has completed processing.
        options.MaxConcurrentCalls = 1; // Indicates the maximum number of concurrent calls to the callback the pump should initiate 
        options.ExceptionReceived += LogErrors; // Allows users to get notified of any errors encountered by the message pump

//=====================WhosebugException on Client.OnMessage======
        if (Client != null && !Client.IsClosed)
            Client.OnMessage(messageHandler, options);  //This is where I get WhosebugException Error. 
    }

    private void LogErrors(object sender, ExceptionReceivedEventArgs e)
    {
        if (e.Exception != null)
            Trace.WriteLine("Queue client processing error: " + e.Exception.Message);
    }

    public void Disconnect()
    {
        Trace.WriteLine($"closing queue {QueueName}");
        Client.Close();
    }
}

这是我的 workerrole 实现。

public class MyWorkerRole : RoleEntryPoint
{
    #region Variables
    ManualResetEvent CompletedEvent = new ManualResetEvent(false);

    MyQueue RequestQueue;           //for Request
    MyPublisher ResponseTopicClient;    //ReponseTopic to notify Subscriber when processing is completed

    Public MyWorkerRole()
    {
        RequestQueue = new MyQueue("JobRequestQueue");
        ResponseTopicClient = new MyPublisher("JobCompletedTopic");
    }


    public override bool OnStart()
    {
        try
        {
            RequestQueue.EstableshConnection();
            ResponseTopicClient.EstableshConnection();
        }
        catch (Exception ex)
        {
            Trace.TraceWarning($"Trace: starting service failed. Error {ex.Message} ");
        }
        return base.OnStart();
    }

    public override void OnStop()
    {
        try
        {
            RequestQueue.Disconnect();
            ResponseTopicClient.Disconnect();
            CompletedEvent.Set();
        }
        catch (Exception ex)
        {
            Trace.TraceWarning($"Trace: stopping service failed with error. {ex.Message} ");
        }
        base.OnStop();
    }

    public override void Run()
    {
        try
        {
            Trace.WriteLine("Trace: Starting Message Processing");

            //var receivedMessage2 = RequestQueue.Client.Receive(new TimeSpan(hours: 0, minutes: 2, seconds: 0));
            RequestQueue.OnMessage((receivedMessage) =>
            {
                try
                {
                    Guid resultGuid = (Guid)receivedMessage.Properties["CorrelationGuid"];
                    Trace.TraceWarning($"Trace: processing message with GUID {resultGuid}");

                    var messageToSend = JobProcessor.ProcessRequest(receivedMessage);
                    if (messageToSend == null)
                    {
                        Trace.TraceError("Trace: > Broken message!");
                        receivedMessage.Abandon();
                        return;
                    }
                    ResponseTopicClient.Send(messageToSend);
                    receivedMessage.Complete();
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Trace: Processing exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
                    Logger.Error("Processing exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
                }
            });
            CompletedEvent.WaitOne();
        }
        catch (Exception ex)
        {
            Trace.TraceError("Trace: Run exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
        }
        finally
        {
            CompletedEvent.Set();
        }
    }
}

当您的 worker 启动时,它会调用 Run 方法,并且在您的代码中,您有:

 //var receivedMessage2 = RequestQueue.Client.Receive(new TimeSpan(hours: 0, minutes: 2, seconds: 0));

RequestQueue.OnMessage((receivedMessage) =>

因此,代码不会等待新消息,因为第一行已被注释,它会调用 OnMessage 方法,该方法一次又一次地递归调用自身,直到 WhosebugException 被触发

在所有情况下,您都需要更改实现,因为 WhosebugException 无论如何都会在收到新消息时发生

想通了。所以,问题不在于代码。在我的存储帐户下的 WADWindowsEventLogsTable 中报告了以下错误。

Faulting application name: WaWorkerHost.exe, version: 2.7.1198.768, time stamp: 0x57159090 Faulting module name: Microsoft.IntelliTrace.Profiler.SC.dll, version: 15.0.27128.1, time stamp: 0x5a1e2eb9 Exception code: 0xc00000fd Fault offset: 0x000000000008ae7b Faulting process id: 0xcf4 Faulting application start time: 0x01d3b75ed89dc2f9 Faulting application path: F:\base\x64\WaWorkerHost.exe Faulting module path: F:\plugins\IntelliTrace\Runtime\x64\Microsoft.IntelliTrace.Profiler.SC.dll

这给了我关于禁用 IntelliTrace 的提示,它工作得很好。以下是通过 VS 2017 发布包时如何禁用。

1.) Right click on your worker role project and select publish from menu
2.) In Settings page->Advanced Settings, uncheck "Enable IntelliTrace" option.