等到事件引发,然后继续编写代码
本文关键字:继续 代码 然后 事件 | 更新日期: 2023-09-27 18:11:35
我使用c# (visual studio 2010)开发了一个Windows窗体应用程序。此应用程序应该连接到服务器并获取数据,然后处理该数据。
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秒才能得到结果。我要做什么?
异步执行此操作的一种可能方法是使用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
将异步地将控制权交还给调用方,直到消息被接收。然后,一旦它在下一行恢复,您就可以更改响应。
另一个选择是使用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;
}
你应该使用回调函数
在代码中,回调函数所在的地方,您应该实现逻辑。
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;
}
}
如果您的服务器可以处理异步调用。您可以使用任何多线程技术,只是您必须在其他线程上调用服务器的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;
}
接收事件还应该能够处理多线程环境