2012-11-16 79 views
2

簡單來說,我試圖通過在單獨的線程上發起一個進程來處理「做某事」來完成我需要做的事情並等待事件發生被提出要說「我已經完成了我需要做的事情」。在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代碼將continute提出的,但是我想要的事件提供反饋,可能使用MessageHasSent某種方式。我嘗試過不同的方法,我想如果我調用Close而不是Set,它可能允許我訪問諸如IsClosed之類的東西。你可以throw an exception或者在事件範圍之外設置一個標誌來檢查,但我覺得這很髒。

有什麼建議嗎?

使用TPL不適用於我的情況,因爲我使用.NET 3.5。

+3

您應該改用TPL和Task類。 – SLaks

+0

從這裏開始? http://msdn.microsoft.com/en-us/data/gg577609.aspx – n8wrl

+0

如果你只是要阻止,直到在主線程中觸發事件首先使用事件的要點是什麼?如果你想使用基於事件的模型,你不應該在啓動異步任務後在主線程中做任何事情;所有的結果處理應該在事件處理程序中。 – Servy

回答

0

因爲它似乎代碼的整個部分在後臺線程已經在運行了,你在做什麼比啓動一個新的線程只是讓更多你可以等待它完成,你最好直接調用Send,而不是異步。

  • 當您完成後,您無需啓動事件。

  • 當需要繼續時,不需要發出主線程信號。

  • 您不需要在List中記錄異常,您可以使用try/catch塊將它們引入SendMessage中。

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; 
} 
+0

我在問題中提到了這個問題 - 「可以拋出異常或者在事件範圍之外設置一個標誌來檢查,但是我覺得這很髒。」這將工作,但我試圖看看是否有一個聰明的方式,我可以返回它。除了對我的問題的評論之外,我可以看到我在這裏做的只是一個巨大的圈子,並不像我當時所想的那樣聰明...... – LukeHennerley

+0

對不起,重讀那個。我同意它不那麼精確,但在某些情況下,它的路要走...... – fixagon