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

时间:2013-03-06 08:56:58

标签: c# events wait

我在C#中遇到了这个问题。我创建了一个方法,从一个名为Phone.GetLampMode();的dll调用一个函数 现在Phone.GetLampMode不会返回任何内容。在“onGetLampModeResponse”事件中返回数据。有没有办法可以在我的方法中等待,直到我从onGetLampModeResponse事件中获取数据?

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

3 个答案:

答案 0 :(得分:9)

一种解决方案是使用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和异步编程的整个概念是< strong>不以这种方式锁定UI线程。

答案 1 :(得分:3)

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

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是必需的。

答案 2 :(得分:0)

看起来现有模型接近基于事件的异步模式(EAP)。您可能希望查看文章Interop with Other Asynchronous Patterns and Types,该文章介绍了如何将此类模式转换为较新的基于任务的异步模式(TAP)。

获得Task(或Task<T>后,您只需Wait即可。