c# - 异步/等待,调用后更新ui组件, "different thread owns it"异常

标签 c# multithreading asynchronous async-await

<分区>

我需要将一些网格列附加到最初只包含几列的网格。创建列是长时间运行的,我正在尝试使用异步/等待,但我收到“调用线程无法访问此对象,因为另一个线程拥有它”的异常,所以有人可以指导我正确的方法做这个。异常发生在 AddRange 调用上。提前致谢。

private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    List<GridViewColumn> cols = await NewGridColsAsync();
    viewGridControl.Columns.AddRange(cols);
}

private async Task<List<GridViewColumn>> NewGridColsAsync()
{
    List<GridViewColumn> cols = new List<GridViewColumn>();

    await Task.Run(() =>
    {
        for (int i = 0; i < 100; i++)
        {
            cols.Add(new GridViewColumn());
        }
    });

    return cols;
}

最佳答案

您正在一个线程(由 Task.Run 创建)创建 GridViewColumn 控件实例,并试图将它们添加到其他线程(UI 线程)。由于对象是在不同线程上创建的,因此您会遇到异常。

正确的实现应该类似于下面的代码。请注意,控件(GridViewColumn 的实例)是使用此代码在 UI 线程上创建的,稍后可用于从主 UI 线程添加为其他控件的子控件:

private async Task<List<GridViewColumn>> NewGridColsAsync()
{
   IEnumerable<DataForColumn> dataForColumns;
   await Task.Run(() =>
   {
      // collect data for columns, runs on thread-pool (non-UI) thread
      dataForColumns = .... 
   });

    // runs on UI thread 
    return dataForColumns.Select(data => CreateGridViewColumn(data)).ToList();
}

关于c# - 异步/等待,调用后更新ui组件, "different thread owns it"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39028284/

相关文章:

java - Java中Thread类的中断方法

.net - 许多线程只需执行一项操作即可在.net中构建耗时的对象

c# - Windows 服务在特定分钟内每小时运行一次

c# - 如何加快写入 Excel 工作表的速度

java - Thread.start() 不初始化 run()

java - 同时线程运行

java - @Async API 端点 Spring Webflux

c++ - 使用 async_write 同时写入不同的套接字

c# - 我需要 "transactionScope.Complete();"吗?

c# - 具有多个连接的事务(MySql、C#)