【问题标题】:Imitate MessageBox - waiting for user's choice模仿MessageBox - 等待用户选择
【发布时间】:2014-01-19 21:02:54
【问题描述】:

我主要使用 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);
}

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

第三次 - 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) 将是最佳选择。在某些情况下,这三种方法中的任何一种都会引起麻烦吗?有人试过这样的吗?

【问题讨论】:

  • 为什么一定要同步?您是否正在寻找这样的东西:stackoverflow.com/q/20917996/1768303
  • @Noseratio 我现在正在使用 Windows Phone,据我所知,没有 ShowDialog - 这就是我在上面尝试此代码的原因。它有效,但我是异步编程的新手,我有一些疑问,可能有很多我不知道的事情。
  • 我不熟悉 WinPhone 开发,但在大多数 GUI 框架中,从后台线程调用任何 GUI 函数都是禁止的(所有 GUI 内容必须在一个线程上)。需要注意的事情,除非 WinPhone 不能那样工作,在这种情况下忽略!
  • 既然你已经澄清了它是 WP,那就有MessageDialogPopupmsdn.microsoft.com/en-us/library/windows/apps/…
  • @dvnrrs 你是对的 - 它的工作原理大致相同。在这种情况下,我在 UI 线程上运行它。对我来说重要的是,在我关闭窗口之前等待之后的代码不会运行。我必须异步运行它 - UI 未被阻止,这使我能够关闭窗口,然后继续进行其余的工作。

标签: c# asynchronous windows-phone-8 async-await


【解决方案1】:

带有TaskCompletionSource 的变体#1 就足够了,这就是TaskCompletionSource 的用途。 #2 和 #3 是不必要的复杂,尤其是带有 Task.Run(..) 的 #3,它浪费了一个池线程来进行阻塞等待。

由于 WP 中没有 Popup 的形式,所有三种方法都可能存在一个主要问题:重入。例如,如果在单击按钮时调用myTask2(),则不会阻止用户再次单击该按钮,这将启动另一个myTask2()。您的应用程序的 UI 工作流程应该考虑到这一点。这是讨论here

【讨论】:

  • 我考虑了这个问题并尝试了更多的东西,我承认 TaskCompletionSource 将是最好的 - 这样做的另一个优点是我可以通过它传递结果。你是对的,在每种方法中都必须考虑 UI。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
相关资源
最近更新 更多