2016-08-03 36 views
2

我在这RelayCommand与UI刷新问题:UI线程不清爽的预期为WPF形式

private RelayCommand _DeleteReferenceCommand; 
public RelayCommand DeleteReferenceCommand 
{ 
    get 
    { 
     return _DeleteReferenceCommand ?? (_DeleteReferenceCommand = new RelayCommand(
      () => 
       { 
       //the 2 next lines trigger properties that will modify some components Visibility on the view 
       ReferencesGridWithPicsUC.TextReplacingGridView = "Deleting the reference. Please wait..."; 
       ReferencesGridWithPicsUC.GridViewVisibility = false; 
       System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor; // mouse cursor change 


       //using multi-threading so that UI updates while a long process takes place in the background 
       Task.Run(() => 
       { 
        Application.Current.Dispatcher.Invoke((new Action(() => 
        { 
        System.Threading.Thread.Sleep(3000); // simulates a long process 
        ReferencesGridWithPicsUC.GridViewVisibility = true; // Sets the UI controls visibility back to previous state 
        System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Hand; // Mouse cursor back to previous value 
       } 
      ))); 
      } 
     ); 
    }, 
    () => { return ReferencesGridWithPicsUC.SelectedReference != null; } 
    )); 
    } 
} 

具体而言,当我启动应用程序并运行的抗冻这个时间码,它可以作为预期的(鼠标光标和控件在Sleep(3000)之前按预期更新并在之后恢复正常。当代码再次执行时,我可以看到该属性已正确更新GridViewVisibility。但UI不再刷新:控件GridViewVisibility更改触发的可见性不会更新,另一方面鼠标光标不断更新,如预期的那样。如果有人可以解决这个血腥的难题,我会在你的债务;)

+2

您在线程池中启动任务,然后立即将所有工作编组到UI线程,从而在整个持续时间内将其阻塞。没有什么是在后台执行的,所以你遇到UI冻结问题并不令人惊讶。 –

回答

4

你必须调用分派器只有更新用户界面。使用Task.Run作为后台任务。

await Task.Run(() => 
    { 
     Thread.Sleep(3000); 
    }); 
在异步委托

new RelayCommand(
      async() => 
      { 

之后

,你会回来的UI线程,因此不再需要的调度。

+0

感谢您的帮助机器学习。 我甚至没有使用异步方法/命令。 只需删除Thread.Sleep(3000);从调度员的电话发出了诀窍。 –