常见的问题"调用线程无法访问此对象,因为另一个线程拥有该对象。"
常见错误测试代码如下:
private void UpdateWrongMethod()
{
try
{
Thread.Sleep(1000);
txtMsg.AppendText("Wrong Method Demo!");
}
catch (Exception ex)
{
UpdateMessage(ex.Message, System.Windows.Media.Brushes.Red);
}
}
private void btnWrongMethod_Click(object sender, RoutedEventArgs e)
{
try
{
Thread th = new Thread(UpdateWrongMethod);
th.Start();
}
catch (Exception ex)
{
UpdateMessage(ex.Message, System.Windows.Media.Brushes.Red);
}
}
正确方式1:
使用 Dispatcher.BeginInvoke 方法
private void UpdateRightMethod()
{
try
{
Thread.Sleep(1000);
this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
{
txtMsg.AppendText("Use dispatcher Begin Invoke is right!");
}));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnRightMethod_Click(object sender, RoutedEventArgs e)
{
Thread th = new Thread(UpdateRightMethod);
th.Start();
}
正确方式2:
使用异步函数, asyn, await 关键字
async Task UpdateMessage(string msg, Brush brush)
{
await this.txtMsg.Dispatcher.InvokeAsync(new Action(() =>
{
Run run = new Run();
Paragraph paragraph = new Paragraph();
run.Foreground = brush;
run.Text = msg;
paragraph.Inlines.Add(run);
paragraph.LineHeight = 1;
this.txtMsg.Document.Blocks.Add(paragraph);
this.txtMsg.ScrollToEnd();
}));
}
private async void btnDirectRight\_Click(object sender, RoutedEventArgs e)
{
for (int i = 1; i < 10; i++)
{
await UpdateMessage($"Test Point {i}", Brushes.Green);
await Task.Delay(500);
}
}