【问题标题】:Doing synchronous calls when dispatcher's PushFrame is used使用调度程序的 PushFrame 时进行同步调用
【发布时间】:2017-10-23 13:47:41
【问题描述】:

我正在为 .Net WPF 应用程序开发一个插件,它使用帧推送技术来实现“负责任的”用户界面。其 SDK 中的每个长时间运行的任务都会调用代码:

  public static void Wait(Task task)
  {
        DispatcherFrame nestedFrame = new DispatcherFrame();
        task.ContinueWith(delegate { return nestedFrame.Continue = false; });
        Dispatcher.PushFrame(nestedFrame);
        task.Wait();
  }

所以典型的SDK的方法可以用下面的代码来模拟:

  private void SdkMethod()
  {
        var t = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1500);
        });

        Wait(t);
  }

这会导致我无法从 UI 线程对 SDK 的方法进行两次同步调用:

  private void OnClick(object sender, RoutedEventArgs e)
  {
        this.sdk.SdkMethod();
        this.sdk.SdkMethod();
  }

在这种情况下有什么方法可以同步调用吗?我无法修改 SDK,只能自己调用​​它。

【问题讨论】:

  • @MickyD,这是一个基于 .Net 4.0 的遗留系统,我无法更改 SDK 中的内容。我知道可以通过适当的 async/await 和完全同步 SDK 调用轻松实现,但我的能力有限。
  • @MickyD,感谢您的回复。但是对于这种特殊情况,我需要同步调用,而不是异步调用。我在我的插件中经常使用异步/等待和任务,问题不在于它们。
  • @MickyD SdkMethod 无法控制 OP,他无法更改。
  • @MickyD、SdkMethod 和 Wait 不是我的,我发布它们是为了演示 SDK 内部的内容以及不让我的调用同步的内容。
  • “这会导致我无法进行两次同步调用” - 为什么,会发生什么,出了什么问题?

标签: c# wpf multithreading synchronization dispatcher


【解决方案1】:

如果我从阅读帖子和 cmets 中理解正确,您想调用 SdkMethod 并让它同步运行。调用它时不会让你知道它何时完成。

如果它是一个 void 方法并且它不是一个任务,那么你将不会得到任何回报。我试图听 Dispatcher Hooks 来完成,但这没有帮助。

我将创建一个具有 Task.Delay 的 aysnc Task 方法,然后在调用之间等待它。这样你就不会打断用户,但你仍然强制调用暂停,直到你调用第二种方法。

private void OnClick(object sender, RoutedEventArgs e)
{
    this.sdk.SdkMethod();
    await DelayAsync(3).ConfigureAwait(false);
    this.sdk.SdkMethod();
}

private async Task DelayAsync(int seconds)
{
    await Task.Delay(seconds * 1000).ConfigureAwait(false);
}

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2014-05-24
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多