我主要使用Windows Phone,我正在尝试创建类似于MessageBox的东西 - 上传并等待用户选择的小窗口(调用窗口等待的线程)。我找到了三种方法来实现这个目标:
FIRST - TaskCompletionSource
在这种情况下,我的任务看起来像这样:
TaskCompletionSource<bool> taskComplete = new TaskCompletionSource<bool>();
private async Task myTask1()
{
window.Show(); // Show window
await taskComplete.Task;
//some job run after User's choice
MessageBox.Show("Job finished");
}
我的窗口关闭事件:
private void WindowClosedEvent1(object sender, EventArgs e)
{
taskComplete.SetResult(true);
}
SECOND - SemaphoreSlim
我的任务和活动:
private SemaphoreSlim mySemaphore = new SemaphoreSlim(0, 1);
private async Task myTask2()
{
window.Show(); // Show window
await mySemaphore.WaitAsync();
//some job run after User's choice
MessageBox.Show("Job finished");
}
private void WindowClosedEvent2(object sender, EventArgs e)
{
mySemaphore.Release();
}
THIRD - EventWaitHandle:
我的任务和活动:
EventWaitHandle waitForUser = new EventWaitHandle(false, EventResetMode.AutoReset, "myEventName");
private async Task myTask3()
{
window.Show(); // Show window
await Task.Run(() => waitForUser.WaitOne());
//some job run after User's choice
MessageBox.Show("Job finished");
}
private void WindowClosedEvent3(object sender, EventArgs e)
{
waitForUser.Set();
}
这三种方法都有效,但我无法决定使用哪种方法。我主要认为1)或2)将是最好的选择。在某些情况下,这三种方法中的任何一种都会引起麻烦吗?有人试过这样的事吗?
答案 0 :(得分:1)
带有TaskCompletionSource
的变体#1就足够了,这就是TaskCompletionSource
的用途。 #2和#3是不必要的复杂,尤其是带有Task.Run(..)
的#3,这会浪费池线程来阻塞等待。
由于WP中Popup
没有形式,所有这三种方法都有一个主要问题:重新入侵。例如,如果在点击按钮时调用myTask2()
,则不会阻止用户再次单击该按钮,这将启动另一个myTask2()
。您的应用的UI工作流程应该考虑到这一点。这是讨论here。