我使用C#开发了一个使用Windows Forms的应用程序(visual studio 2010)。此应用程序应连接到服务器并获取数据,然后处理该数据。
public partial class Form1 : Form
{
public string Result = "";
MyServer server = new MyServer();
public Form1()
{
InitializeComponent();
server.RecieveMessage += new MyServer.RecieveMessageEventHandler(server_RecieveMessage);
}
void server_RecieveMessage(object sender, string message)
{
Result = message;
}
public string SendCommand(string Command)
{
server.Send(Command);
//wait untill RecieveMessage event raised
//process Data is recieved
server.Send(AnotherCommand);
//wait untill RecieveMessage event raised
//process Data is recieved
....
//till i get what i want
return Result;
}
所以我想在server.Send(Message)
之后等待,直到我得到事件的结果。有时需要4到5秒才能得到结果。我该怎么办?
答案 0 :(得分:4)
异步执行此操作的一种可能方法是使用TaskCompletionSource<T>
。它看起来像这样:
public async Task<string> SendMessageAsync(string message)
{
var tcs = new TaskCompletionSource<string>();
ReceiveMessangeEventHandler eventHandler = null;
eventHandler = (sender, returnedMessage) =>
{
RecieveMessage -= eventHandler;
tcs.SetResult(returnedMessage);
}
RecieveMessage += eventHandler;
Send(message);
return tcs.Task;
}
现在,当您想要调用它并异步等待结果时,请执行以下操作:
public async void SomeEventHandler(object sender, EventArgs e)
{
var response = await server.SendMessageAsync("HelloWorld");
// Do stuff with response here
}
SendMessageAsync
将异步地将控制权交还给调用者,直到收到消息。然后,一旦它在下一行恢复,您就可以改变响应。
答案 1 :(得分:0)
您应该使用回调函数。
在回调函数所在的代码中,您应该实现逻辑。
void server_RecieveMessage(object sender, string message)
{
Result = message; // You have Your incoming data here. If this code runs, You have already waited the next message.
//process Data is recieved
if (till i get what i want)
{
// Use Result as final value.
// Close connection.
server.RecieveMessage -= server_RecieveMessage;
}
}
答案 2 :(得分:0)
其他选项是使用AutoResetEvent
类来同步您的异步操作:
public partial class Form1 : Form
{
public string Result = "";
private int timeOut = 10000;
MyServer server = new MyServer();
AutoResetEvent res = new AutoResetEvent(false);
public Form1()
{
InitializeComponent();
server.RecieveMessage += new MyServer.RecieveMessageEventHandler(server_RecieveMessage);
}
void server_RecieveMessage(object sender, string message)
{
Result = message;
res.Set();
}
public string SendCommand(string Command)
{
server.Send(Command);
res.WaitOne(timeOut);
//wait for 10 seconds or untill RecieveMessage event raised
//process Data is recieved
server.Send(AnotherCommand);
res.WaitOne(timeOut);
//wait for 10 seconds or untill RecieveMessage event raised
//process Data is recieved
....
//till i get what i want
return Result;
}
答案 3 :(得分:0)
如果您的服务器可以处理异步调用。您可以使用任何多线程技术,只需在其他线程上调用服务器的Send方法即可。如果您的服务器支持SendAsync方法。您也可以使用
public partial class Form1 : Form
{
public string Result = "";
MyServer server = new MyServer();
public Form1()
{
InitializeComponent();
server.RecieveMessage += new MyServer.RecieveMessageEventHandler(server_RecieveMessage);
}
void server_RecieveMessage(object sender, string message)
{
Result = message;
}
public string SendCommand(string Command)
{
Task.Factory.StartNew(() =>
server.Send(Command)
);
//wait untill RecieveMessage event raised
//process Data is recieved
Task.Factory.StartNew(() =>
server.Send(AnotherCommand));
//wait untill RecieveMessage event raised
//process Data is recieved
....
//till i get what i want
return Result;
}
receive事件也应该能够处理多线程环境。