2012-10-17 236 views
1

我已經偶然發現了這個問題多次,主要是用黑客解決它,但希望看到一個「proprer」的方式來做到這一點。C#阻止等待響應

我正在寫一個通信協議,與我的端點詢問「查詢」的方式非常類似於RPC,他們收到「答覆」。

現在...我想實現一個名爲SendCommand的函數,它將發出一個查詢,然後等待對該問題的回覆,並將其返回。

所以我可以做類似

int outside_temp = SendCommand(What is the temperature outside).ToInt(); 

這樣做的問題是,消息發送和異步接收的,而我由一個新的消息,事件,和它是什麼通知。我需要阻止線程,直到對提到的查詢的回覆已到達,提取其數據內容並將其返回給調用者。

我的問題是阻塞線程。阻塞線程不是問題,我們正在討論一個多線程應用程序,所以用戶界面不會凍結等,但問題是實現這一目標的正確方法是什麼?

我正在考慮一些東西,在SendCommand函數內部初始化一個信號燈,等待它,並釋放收到消息的事件處理程序中的信號量(在檢查它是正確的消息之後)?

問候, axos88

+2

你應該看看用C#5提供的異步方法。如果你可以讓你的代碼遵循基於任務的異步模式,其餘的將變得更加簡單。 –

回答

2

所以你的問題是關於阻止當前線程並等待答案嗎? 我會使用ManualResetEvent來同步調用者和回調。

應該可以通過它接受一個回調方法的對象的發送方法來發送你的RPC調用,您可以像這樣編寫你的SendCommand方法:

int SendCommand(int param) 
{ 
    ManualResetEvent mre = new ManualResetEvent(false); 

    // this is the result which will be set in the callback 
    int result = 0; 

    // Send an async command with some data and specify a callback method 
    rpc.SendAsync(data, (returnData) => 
         { 
          // extract/process your return value and 
          // assign it to an outer scope variable 
          result = returnData.IntValue; 
          // signal the blocked thread to continue 
          mre.Set(); 
         }); 

    // wait for the callback 
    mre.WaitOne(); 
    return result; 
} 
0

你可以做的是,旋轉一個新的線程調用SendCommand(..),只是等待遠線程與睡眠,直到你的SendCommand發送信號。

例如:

volatile bool commandCompleted=false; 
Thread sendCommandThread=new Thread(()=>{ 
    SendCommand(...,()=>{ 
commandCompleted=true; 
}) 

while(!commandCompleted) 
{ 

    Thread.Sleep(100); 
} 
}); 
+0

不要創建線程來執行任務,無論是用戶線程池還是任務類int .NET 4.0 –

+2

親愛的downvoter,如果你只是因爲我使用Thread而不是ThreadPool或Task而投票,我有話要說這只是一個例子如何解決這種問題並不是有效的。 – crypted

+1

你實際上給了一個反例的例子,應該避免的例子。 –