摆脱try / catch - 从消息队列中读取

时间:2011-09-15 00:37:17

标签: c# try-catch message-queue

如何修改以下代码块,使其不依赖于try / catch块和IOTimeout。每1分钟调用一次此函数。所以我只想处理在最后一次调用之后排队的Id列表。

如果我刚刚在队列中没有消息等待时收到空值,那将解决我的问题,但API http://msdn.microsoft.com/en-us/library/system.messaging.messagequeue.receive.aspx 显示接收的所有签名都是同步的(我不能阻塞线程)或者是我必须通过try / catch块进入的MessageQueueException异常。在阅读了一些建议不使用try / catch来控制程序流程的文章后,我想避免这种情况。

    #pragma warning disable
    public void ConsumeEvents2()
    {
        var listOfJobs = new List<int>();

        try {
            while (true) { 
                // receive all messages and add in a list to process later
                Message message = messageQueue.Receive(new TimeSpan(0,0,3));
                JobEvent evt = (JobEvent)message.Body;
                listOfJobs.Add(evt.DataNumber);
            }
        } catch (MessageQueueException e) {
            if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) {
                // process the numbers received
                ProcessJobList(listOfJobs);
                return;
            }
            throw;
        }

    }
    #pragma warning restore

2 个答案:

答案 0 :(得分:1)

尝试不直接访问它,看一下microsoft的这段代码 -

using System;
using System.Windows.Controls;
using System.Windows.Messaging;

namespace ReceivingApplication
{
  public partial class Receiver : UserControl
  {
    public Receiver()
    {
        InitializeComponent();

        LocalMessageReceiver messageReceiver =
            new LocalMessageReceiver("receiver",
            ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain);
        messageReceiver.MessageReceived += messageReceiver_MessageReceived;
        try
        {
            messageReceiver.Listen();
        }
        catch (ListenFailedException)
        {
            output.Text = "Cannot receive messages." + Environment.NewLine +
                "There is already a receiver with the name 'receiver'.";
        }
    }

    private void messageReceiver_MessageReceived(
        object sender, MessageReceivedEventArgs e)
    {
        e.Response = "response to " + e.Message;
        output.Text =
            "Message: " + e.Message + Environment.NewLine +
            "NameScope: " + e.NameScope + Environment.NewLine +
            "ReceiverName: " + e.ReceiverName + Environment.NewLine +
            "SenderDomain: " + e.SenderDomain + Environment.NewLine +
            "Response: " + e.Response;
    }
  }
}

答案 1 :(得分:0)

在Windows窗体应用程序中,当在应用程序中的任何位置(在主线程上或在异步调用期间)抛出异常时,您可以通过在Application上注册ThreadException事件来捕获它。通过这种方式,您可以摆脱为所有方法添加try / catch。

Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod)

private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t)
{
    //Exception handling...
}

Application.ThreadException Event

对于ASP.NET应用程序

  

要在页面中创建全局处理程序,请为其创建处理程序   System.Web.UI.TemplateControl.Error事件。创建一个   应用程序范围的错误处理程序,在Global.asax文件中,添加代码   System.Web.HttpApplication.Error事件。调用这些方法   如果页面或应用程序中的任何位置发生未处理的异常,   分别。您可以从中获取有关最新错误的信息   GetLastError方法。

以下是一些有趣的主题。

.NET - What's the best way to implement a “catch all exceptions handler”

Why global.asax Application_Error method does not catch exceptions thrown by ASMX service?

global.asax Application_Error not firing