【问题标题】:My UI thread is blocked when await Dispatcher.BeginInvoke... (using WPF and WCF)当等待 Dispatcher.BeginInvoke...(使用 WPF 和 WCF)时,我的 UI 线程被阻塞
【发布时间】:2014-02-04 22:59:30
【问题描述】:

我有一个 WPF 窗口,它在其构造函数中创建并启动一个计时器。计时器已用事件触发一个方法 (SyncPTUpdate),该方法使用 BeginInvoke 将另一个方法 (PTProgressUpdateInThread) 调用到 Window 的线程上。然后这会异步调用 WCF 调用(使用 TAP 模式,由 VS 2013 自动生成)。

当我人为地延长 WCF 调用的持续时间(在服务器组件中使用 thread.sleep)时,我的 WPF 应用程序的 UI 会冻结。一开始不是,但过了几秒钟。

我哪里错了?

public delegate void PTProgressDelegate();

// this method is called from a periodically firing timer (System.Timers)
private async void SyncPTUpdate(object sender, ElapsedEventArgs e)
{
    await this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new PTProgressDelegate(PTProgressUpdateInThread));
}

private async void PTProgressUpdateInThread()
{
    PTMapFieldClient = new FieldClient();
    ServiceField.BlokPTProgress PTProgressFromServer = await PTMapFieldClient.GetPTProgressAsync(variousparametershere);
    PTMapFieldClient.Close();

    // now use the results of the WCF call to update the Window UI
    //...
}

【问题讨论】:

  • 顺便说一句,使用 System.Action 代表。
  • 你为什么要在 UI 线程上运行?
  • 你的意思是我为什么要在 Window 线程上运行计时器?好点,只是因为我来自单线程文化,只是慢慢地掌握了多线程。我认为一个新的计时器无论如何都会产生一个新线程?
  • 如果你想让你的定时器在主线程上触发,你可以使用System.Windows.Threading.DispatcherTimer
  • 听起来UI卡死可能是你的cmets造成的。 // now use the results of the WCF call to update the Window UI

标签: c# wpf multithreading wcf tap


【解决方案1】:

Dispatcher.BeginInvoke() 通常作为一种异步处理方式呈现,其好处是不必创建/涉及另一个线程。

但这意味着它只对小型、轻量级的工作有益。最好的方法是将调用 PTProgressUpdateInThread() 推送到 ThreadPool。或者使用线程定时器。
无论如何,您没有使用await 之后的结果。

【讨论】:

  • 谢谢,将看看将作业推送到 ThreadPool。已更新我的代码以显示等待的结果用于更新 Window UI(因此在我假设的 Window 线程上需要它)。
  • 您的解决方案对我来说效果很好,谢谢。我最终实现了这一点,以将工作负载转移到不同的线程上。 Thread MyNewThread = new Thread(new ThreadStart(() => { this.Dispatcher.BeginInvoke(new Action(() => { PTProgressUpdateInThread(PTProgress); })); // 将接收到的数据推送到 UI 线程 } ) ); MyNewThread.Start();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多