等待直到引发的事件,然后继续代码

时间:2015-09-08 06:57:48

标签: c# winforms

我使用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秒才能得到结果。我该怎么办?

4 个答案:

答案 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事件也应该能够处理多线程环境。