Wait inside method until event is captured

痴心易碎 提交于 2019-12-18 15:13:10

问题


I have this issue with a method in C#. I made a method that calls a function from a dll its called Phone.GetLampMode(); Now Phone.GetLampMode doesnt return anything. The data gets returned in a event the 'onGetLampModeResponse' event. Is there a way i can wait in my method until i get the data from the onGetLampModeResponse event?

public bool checkLamp(int iLamp)
{
    Phone.ButtonIDConstants btn = new Phone.ButtonIDConstants();
    btn = Phone.ButtonIDConstants.BUTTON_1;
    btn += iLamp;
    Phone.GetLampMode(btn, null);

    return true;
}

private void Phone_OnGetLampModeResponse(object sender, Phone.GetLampModeResponseArgs e)
{
    var test = e.getLampModeList[0].getLampMode.ToString();    
}

回答1:


One solution is to use AutoResetEvent:

public bool checkLamp(int iLamp)
{
    Phone.ButtonIDConstants btn = new Phone.ButtonIDConstants();
    btn = Phone.ButtonIDConstants.BUTTON_1;
    btn += iLamp;

    AutoResetEvent waitHandle = new AutoResetEvent(false); 

    // Pass waitHandle as user state
    Phone.GetLampMode(btn, waitHandle);

    // Wait for event completion
    waitHandle.WaitOne();

    return true;
}

private void Phone_OnGetLampModeResponse(object sender, Phone.GetLampModeResponseArgs e)
{
    var test = e.getLampModeList[0].getLampMode.ToString();

    // Event handler completed
    // I guess there is some UserState property in the GetLampModeResponseArgs class
    ((AutoResetEvent)e.UserState).Set();
}

NOTE: Ad you're using Phone as a static class/variable, one can think you're developing on Windows Phone... If it is the case, do note that the whole concept of WP and async programming is to not lock the UI thread in a such way.




回答2:


You can wrap the handler in an asynchronous method, which should look something like this (untested):

public async Task<bool> checkLamp(int iLamp)
{
    Phone.ButtonIDConstants btn = new Phone.ButtonIDConstants();
    btn = Phone.ButtonIDConstants.BUTTON_1;
    btn += iLamp;

    var tcs = new TaskCompletionSource<bool>();
    var handler = (sender, e) => {
        Phone.OnGetLampModeResponse -= handler;
        var test = e.getLampModeList[0].getLampMode.ToString();
        tcs.SetResult(true);
    };
    Phone.OnGetLampModeResponse += handler;

    Phone.GetLampMode(btn, null);

    return tcs.Task;
}

In your calling method, you would write:

var returnValue = await checkLamp(iLamp);

This has the advantage that your user interface does not block while the process is waiting for the response.

Here's a blog entry on this issue. Note that Framework 4.5 is required.

  • http://blogs.msdn.com/b/lucian/archive/2012/11/28/how-to-await-a-button-click.aspx



回答3:


It looks like the existing model is close to the Event-based Asynchronous Pattern (EAP). You might want to look at the article Interop with Other Asynchronous Patterns and Types which describes how to convert such a pattern to the newer Task-based Async Pattern (TAP).

Once you have a Task (or Task<T>, you can just Wait for it.



来源:https://stackoverflow.com/questions/15242831/wait-inside-method-until-event-is-captured

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!