【发布时间】:2018-05-16 11:55:31
【问题描述】:
我有一个线程可以改变字段
private void SongChange(object sender, RoutedEventArgs e)
{
SongChangeAction();
songLength = (int)BGMPlayer.NaturalDuration.TimeSpan.TotalSeconds;
songProgress = new Thread(SongProgressUpdate) { IsBackground = true };
songProgress.Start();
}
private void SongProgressUpdate()
{
while (true)
{
Dispatcher.Invoke(() => { workingResources.SongProgress = BGMPlayer.Position.TotalSeconds / songLength * 100; });
Thread.Sleep(1000);
}
}
注意:songLength 是 double,BGMPlayer 是 MediaElement 在后台播放音乐,workingResources.SongProgress 是 double 绑定到 Progress Bar
当我使用“X”按钮或任务栏关闭程序时,程序抛出异常System.Threading.Tasks.TaskCanceledException 即使我尝试设置线程IsBackground = true,但如果我使用 Visual Studio 停止程序,它不会抛出异常。
程序抛出异常在行:
Dispatcher.Invoke(() => { workingResources.SongProgress = BGMPlayer.Position.TotalSeconds / songLength * 100; });
我可以通过使用 try/catch 来防止它,但我想找到更有效的方法
【问题讨论】:
-
在您的情况下,这是预期的异常。当您关闭主窗口时 - WPF 会优雅地关闭。如果您在调度程序开始关闭时尝试执行
Dispatcher.Invoke- 它会抛出您看到的异常。您可以切换到BeginInvoke,捕获该异常,或者更好地使用其他方法来实现您的目标,不需要Dispatcher.Invoke、单独的线程和while (true)循环。 -
BGMPlayer 是一个控件。如果我使用另一个线程使用 while 循环,那么应用程序将抛出 Thread.InvalidOperation
标签: c# multithreading exception