等到事件引发,然后继续编写代码

本文关键字:继续 代码 然后 事件 | 更新日期: 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;
}

接收事件还应该能够处理多线程环境