如何强制BusyIndi​​cator?

Akr*_*rem 3 c# wpf xaml busyindicator

我使用Extended WPF Toolkit BusyIndi​​cator

我的Xaml

<extToolkit:BusyIndicator Name="wait" IsBusy="False" Cursor="Wait" Grid.ColumnSpan="3" Margin="10,10,10,10"/>
Run Code Online (Sandbox Code Playgroud)

我的代码:

private void esp_Click(object sender, RoutedEventArgs e)
{
    wait.IsBusy = true;

    // My work here make some time to finish

    wait.IsBusy = false;
}
Run Code Online (Sandbox Code Playgroud)

但它永远不会显示,我尝试在函数的最后使MessageBox在MessageBox之后显示BusyIndi​​cator,

我试过了

wait.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send,
                       (Action)delegate
{
    wait.IsBusy = true;
});
Run Code Online (Sandbox Code Playgroud)

但我一无所获!这里的问题在哪里我无法解决?

我发现了一个类似的问题,但我没有出现相同的问题,指示器显示但在完成功能后.

mac*_*kow 7

问题是你在调度程序的线程中执行所有工作(我假设这esp_Click是一个事件处理程序).这实际上意味着在执行长任务时,UI不会更新.

您需要在单独的线程中执行工作 - 创建新线程,使用线程池或创建任务.设置IsBusytrue开始之前和false完成工作之后.从另一个线程Dispatcher.BeginInvoke/Invoke更新时需要使用wait.IsBusy.

示例代码:

private void LongRunningTask() 
{
   // your long running code

   // after you complete:
   Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send,
                           (Action)delegate
    {
        wait.IsBusy = false;
    }); 
}

private void esp_Click(object sender, RoutedEventArgs e)
{
   wait.IsBusy = true; // either here, or in your long running task - but then remember to use dispatcher

   var thread = new Thread(LongRunningTask);
   thread.Start();

   // OR

   ThreadPool.QueueUserWorkItem(state => LongRunningState());

   // OR, in .NET 4.0

   Task.Factory.StartNew(LongRunningTask);
}
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案都不处理异常 - 您必须自己添加错误处理(或在最后一个示例的情况下使用任务延续).