当我查询数据库并更新 BackgroundWorker DoWork 中的DataGrid时,我试图使不确定的ProgressBar动画平稳运行.我了解我无法在 DoWork 中更新UIThread,因此我使用Dispatcher.BeginInvoke访问DataGrid,但是我仍然收到由另一个线程拥有的异常.

I am trying to keep my indeterminate ProgressBar animation running smoothly as I query database and updating DataGrid in DoWork in BackgroundWorker. I understand that I cannot update UIThread in DoWork, so I use Dispatcher.BeginInvoke to access DataGrid, yet I still receive the owned-by-another-thread exception.


为什么会这样? DoWork应该处于开启状态 UIThread和Dispatcher拥有的BackgroundWorker线程 允许我的DoWork访问我的GUI.

Why is this happening? DoWork should be on BackgroundWorker's thread owned by UIThread, and Dispatcher should allow my DoWork to access my GUI.

进一步查看BackgroundWorker,建议UI操作应在 ProgressChanged() 中处理.但是,如果我将所有数据库/GUI操作移至 ProgressChanged() 并将Thread.Sleep(5000)放在 DoWork() 上,以模拟需要处理的内容,从而为留出足够的时间> ProgressChanged() 运行,尽管ProgressBar继续其不确定的平滑动画,但GUI尚未更新.

Looking further into BackgroundWorker suggest UI operation should be handled in ProgressChanged(). But if I move all database/GUI operation to ProgressChanged() and put a Thread.Sleep(5000) on DoWork() to emulate something to work on to lend enough time for ProgressChanged() to run, the GUI is not being updated, although the ProgressBar continue its indeterminate smooth animation.


我在BackgroundWorker线程上调用了Thread.Sleep(5000). ProgressChanged()应该花5秒钟查询数据库,然后 更新GUI.为什么不呢?

I called a Thread.Sleep(5000) on BackgroundWorker thread. ProgressChanged() should spend 5 seconds querying database and updating GUI. Why not?


<DataGrid x:Name="myDataGrid" ScrollViewer.CanContentScroll="True" 
          EnableRowVirtualization="True" EnableColumnVirtualization="True"
          Height="500" MaxHeight="500" />

<ProgressBar x:Name="myProgressBar" Height="20" Width="400"
             IsIndeterminate="True" Visibility="Visible" />

<Button x:Name="mySearch" Click="btnSearch_Click">Search</Button>


private BackgroundWorker bgw = new BackgroundWorker();

private void btnSearch_Click(object sendoer, RoutedEventArgs e)
    bgw.WorkerReportsProgress = true;
    bgw.ProgressChanged += ProgressChanged;
    bgw.DoWork += DoWork;
    bgw.RunWorkerCompleted += BGW_RunWorkerCompleted;


private void DoWork(object sender, DoWorkEventArgs e)
    // Thread.Sleep(5000);
    using (SqlConnection conn = new SqlConnection(connStr))
        using (SqlCommand cmd = new SqlCommand("SELECT * FROM " + MyTableName, conn))
            using (SqlDataReader rdr = cmd.ExecuteReader())
                while (rdr.Read())
                    Dispatcher.BeginInvoke(new Action(() =>
                            Id = rdr.GetInt32(0),
                            Name = rdr.GetString(1).ToString(),

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
   // Paste code from DoWork and uncomment Thread.Sleep(5000)

private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

 1 条回答