2012-10-17 150 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

你实际上给了一个反例的例子,应该避免的例子。 –