在方法内部等待,直到捕获事件

本文关键字:事件 方法 内部 等待 | 更新日期: 2023-09-27 18:02:24

我在c#中的一个方法有这个问题。我做了一个方法,从dll调用一个函数,它被称为Phone.GetLampMode();现在Phone.GetLampMode没有返回任何东西。数据在事件' onGetLampModeResponse '事件中返回。是否有一种方法,我可以在我的方法等待,直到我从ongetlampmoderresponse事件获得数据?

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();    
}

在方法内部等待,直到捕获事件

一个解决方案是使用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();
}

注意:如果你使用Phone作为静态类/变量,人们可能会认为你是在Windows Phone上开发游戏……如果是这种情况,请注意,WP和异步编程的整个概念是不以这种方式锁定UI线程

您可以将处理程序包装在一个异步方法中,看起来应该像这样(未经测试):

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;
}

在你的调用方法中,你可以这样写:

var returnValue = await checkLamp(iLamp);

这样做的好处是,当进程等待响应时,用户界面不会阻塞。

这是关于这个问题的博客条目。注意需要使用Framework 4.5。

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

看起来现有的模型很接近基于事件的异步模式(EAP)。您可能想看一下文章"与其他异步模式和类型互操作",其中描述了如何将这种模式转换为较新的基于任务的异步模式(TAP)。

一旦你有了Task(或Task<T>),你可以直接用Wait代替。