繁体   English   中英

WPF:调用线程无法访问此对象,因为其他线程拥有它

[英]WPF: The calling thread cannot access this object because a different thread owns it

我知道也有类似的问题,例如“ 在这里这里” ,我都看了看,但是它们似乎对我不起作用。

我有一个线程:

private void Sample()
{
      Thread t = new Thread(new ThreadStart(Sample_Thread));
      t.SetApartmentState(ApartmentState.STA);
      t.Start();
}

在Sample_Thread中,我以前叫MessageBox可以正常工作。

private void Sample_Thread()
{
     try{ ... }
     catch(Exception e)
     {
          MessageBox.Show("SampleText");
     }
}

现在,我尝试调用ModernDialog而不是MessageBox ,它给我错误'The calling thread cannot access this object because a different thread owns it.' 所以我将代码更改为此:

private void Sample_Thread()
{
     try{ ... }
     catch(Exception e)
     {
            Dispatcher.CurrentDispatcher.Invoke(() =>
            {
                ModernDialog.ShowMessage("SampleText");
            });
     }
}

但这仍然有同样的错误,我该如何解决? 谢谢!

有很多重复项,所有重复项都起作用,并且都说相同的话:您不能从另一个线程修改UI。 显示消息框不会修改UI。 此限制适用于至少追溯到Windows 95 其他操作系统(例如Linux)的所有Windows版本。

您也不需要Invoke来更新UI或原始线程即可在后台执行任何操作。 .NET允许您使用Task.Run在后台执行工作,等待其结果并处理任何异常。 您唯一需要写的是:

private void SomeMethod()
{
...
}

private async void myButton_Click(object sender, RoutedEventArgs e)
{
    try
    {
        await Task.Run(someMethod);
    }
    catch(Exception e)
    {
        ModernDialog.ShowMessage(e.ToString());
     }
}

如果要在后台处理时更新UI(例如显示进度),则可以使用IProgress< T>如此处所述 )来报告任何类型的消息,例如int,string或full class:

private void SomeMethod(IProgress<string> progress)
{
   foreach(...)
   {
       progress.Report("foo");
       ....
   }
}

private async void myButton_Click(object sender, RoutedEventArgs e)
{
    var progressIndicator = new Progress<string>(reportProgressMethod);
    try
    {
        await Task.Run(()=>someMethod(progressIndicator());
    }
    catch(Exception e)
    {
        ModernDialog.ShowMessage(e.ToString());
    }
}

async void仅应用于事件处理程序。 在所有其他情况下,不返回结果的异步方法的方法签名应为async Task

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM