在方法内部等待,直到捕获事件
本文关键字:事件 方法 内部 等待 | 更新日期: 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
代替。