返回正在等待的事件的反馈

时间:2012-11-16 14:50:28

标签: c# events .net-3.5 event-handling

简单来说,我要做的就是通过在一个单独的线程上触发一个进程来处理“Doing Something”来做我需要做的事情并等待一个事件被提出来说“我已经完成了什么我需要去做”。在EventArgs中虽然我将有一个属性来处理在此过程中可能遇到的任何错误。以下是我的情况的简化示例。

public class MessageHandler
{
  private AutoResetEvent MessageHasSent = new AutoResetEvent(false);
  public void SendMessage()
  {
    MessageSender ms = new MessageSender();
    ms.MessageSent += new EventHandler<MessageSentEventArgs>(MessageHandler_MessageSent);

    Thread t = new Thread(ms.Send());
    t.Start();

    MessageHasSent.WaitOne();
    //Do some check here

    //Same again but for "Message recieved"
  }
  void MessageHandler_MessageSent(object sender, MessageSentEventArgs e)
  {
    if (e.Errors.Count != 0)
    {
      //What can I do here to return to the next step after waitone?
    }
    else
      MessageHasSent.Set();
  }
}
public class MessageSender
{
  public event EventHandler<MessageSentEventArgs> MessageSent;
  public void Send()
  {
    //Do some method which could potentiallialy return a List<Error>
    MessageSent(this, new MessageSentEventArgs() { Errors = new List<Error>() });
  }
}
public class Error { }
public class MessageSentEventArgs : EventArgs
{
  public List<Error> Errors;
}

基本上一旦事件从Send引出,代码就会继续,但是我想要某种方式来提供反馈,可能使用MessageHasSent。我尝试了不同的方法,我想如果我拨打Close而不是Set,它可能会允许我访问IsClosed之类的内容。您可以throw an exception或设置事件范围之外的标志来检查,但我觉得这很脏。

有什么建议吗?

使用TPL不适用于我的情况,因为我使用的是.NET 3.5。

2 个答案:

答案 0 :(得分:0)

这将做你想要的:

public class MessageHandler
{
    private AutoResetEvent MessageHasSent = new AutoResetEvent(false);
    private bool IsSuccess = false;
    public void SendMessage()
    {
        MessageSender ms = new MessageSender();
        ms.MessageSent += new EventHandler<MessageSentEventArgs>(MessageHandler_MessageSent);

        Thread t = new Thread(ms.Send());
        t.Start();

        MessageHasSent.WaitOne();
        if(IsSuccess)
            //wohooo
        else
            //oh crap

        //Same again but for "Message recieved"
    }
    void MessageHandler_MessageSent(object sender, MessageSentEventArgs e)
    {
        IsSuccess = e.Errors.Count == 0;
        MessageHasSent.Set();
    }
}
public class MessageSender
{
    public event EventHandler<MessageSentEventArgs> MessageSent;
    public void Send()
    {
        //Do some method which could potentiallialy return a List<Error>
        MessageSent(this, new MessageSentEventArgs() { Errors = new List<Error>() });
    }
}
public class Error { }
public class MessageSentEventArgs : EventArgs
{
    public List<Error> Errors;
}

答案 1 :(得分:0)

因为看起来整个代码段已经在后台线程中运行了,而你只是启动一个新线程就可以让它等待它完成,你会更好只是直接调用Send,而不是异步调用。

  • 完成后,您无需启动活动。

  • 当需要继续时,您无需向主线程发出信号。

  • 您不需要在List中记录异常,只需抛出它们并使用try / catch块在SendMessage中捕获它们。