【发布时间】:2018-03-08 21:00:55
【问题描述】:
我正在尝试部署我的第一个 Azure 辅助角色,并且在服务启动期间调用 Run() 方法时遇到此错误。
未知模块中发生了“System.StackOverflowException”类型的未处理异常。
我尝试远程调试我的代码,但在这一行抛出了错误。 MyPublisher 类似于 MyQueue,但它包装了 Topic 而不是 Queue。知道为什么 QueueClient.OnMessage 会导致 StackOverflow 吗?
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
//=====================StackOverFlowException on Client.OnMessage======
if (Client != null && !Client.IsClosed)
Client.OnMessage(messageHandler, options); //This is where I get StackOverflowException 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();
}
}
这是我的工作角色实现。
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();
}
}
}
【问题讨论】:
-
谢谢。我理解递归,但我只调用一次 Client.OnMessage。 OnMessage 不只是注册在队列中收到实际消息时采取的操作吗?此外,诊断数据并不表明调用了 Action 委托。没有任何东西被发送到队列中,因为我将从单独的应用程序发送请求。我可以尝试从代码中删除主题,看看是否能解决问题,但我想了解这会如何影响队列。
标签: c# azure azure-worker-roles azure-queues