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

本文翻译自:The calling thread cannot access this object because a different thread owns it

My code is as below 我的代码如下

public CountryStandards()
{
    InitializeComponent();
    try
    {
        FillPageControls();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Country Standards", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

/// <summary>
/// Fills the page controls.
/// </summary>
private void FillPageControls()
{
    popUpProgressBar.IsOpen = true;
    lblProgress.Content = "Loading. Please wait...";
    progress.IsIndeterminate = true;
    worker = new BackgroundWorker();
    worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
    worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
    worker.WorkerReportsProgress = true;
    worker.WorkerSupportsCancellation = true;
    worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.RunWorkerAsync();                    
}

private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    GetGridData(null, 0); // filling grid
}

private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    progress.Value = e.ProgressPercentage;
}

private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
    worker = null;
    popUpProgressBar.IsOpen = false;
    //filling Region dropdown
    Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
    objUDMCountryStandards.Operation = "SELECT_REGION";
    DataSet dsRegionStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
    if (!StandardsDefault.IsNullOrEmptyDataTable(dsRegionStandards, 0))
        StandardsDefault.FillComboBox(cmbRegion, dsRegionStandards.Tables[0], "Region", "RegionId");

    //filling Currency dropdown
    objUDMCountryStandards = new Standards.UDMCountryStandards();
    objUDMCountryStandards.Operation = "SELECT_CURRENCY";
    DataSet dsCurrencyStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
    if (!StandardsDefault.IsNullOrEmptyDataTable(dsCurrencyStandards, 0))
        StandardsDefault.FillComboBox(cmbCurrency, dsCurrencyStandards.Tables[0], "CurrencyName", "CurrencyId");

    if (Users.UserRole != "Admin")
        btnSave.IsEnabled = false;

}

/// <summary>
/// Gets the grid data.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="pageIndex">Index of the page.( used in case of paging)   </pamam>
private void GetGridData(object sender, int pageIndex)
{
    Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
    objUDMCountryStandards.Operation = "SELECT";
    objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
    DataSet dsCountryStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
    if (!StandardsDefault.IsNullOrEmptyDataTable(dsCountryStandards, 0) && (chkbxMarketsSearch.IsChecked == true || chkbxBudgetsSearch.IsChecked == true || chkbxProgramsSearch.IsChecked == true))
    {
        DataTable objDataTable = StandardsDefault.FilterDatatableForModules(dsCountryStandards.Tables[0], "Country", chkbxMarketsSearch, chkbxBudgetsSearch, chkbxProgramsSearch);
        dgCountryList.ItemsSource = objDataTable.DefaultView;
    }
    else
    {
        MessageBox.Show("No Records Found", "Country Standards", MessageBoxButton.OK, MessageBoxImage.Information);
        btnClear_Click(null, null);
    }
}

The step objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null; 步骤objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null; objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null; in get grid data throws exception 在获取网格数据时抛出异常

The calling thread cannot access this object because a different thread owns it. 调用线程无法访问该对象,因为其他线程拥有它。

What's wrong here? 怎么了


#1楼

参考:https://stackoom.com/question/epvB/调用线程无法访问该对象-因为其他线程拥有它


#2楼

您需要更新到用户界面,因此请使用

Dispatcher.BeginInvoke(new Action(() => {GetGridData(null, 0)})); 

#3楼

Another good use for Dispatcher.Invoke is for immediately updating the UI in a function that performs other tasks: Dispatcher.Invoke另一个好用法是立即执行执行其他任务的功能中的UI:

// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);

I use this to update button text to " Processing... " and disable it while making WebClient requests. 我使用它来将按钮文本更新为“正在处理... ”,并在发出WebClient请求时将其禁用。


#4楼

For some reason Candide's answer didn't build. 由于某种原因,Candide的答案没有建立。 It was helpful, though, as it led me to find this, which worked perfectly: 但是,这很有帮助,因为它使我找到了这个,它非常有效:

System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
    {
       //your code here...
    }));

#5楼

To add my 2 cents, the exception can occur even if you call your code through System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke() . 要加2美分,即使您通过System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()调用代码,也会发生异常。
The point is that you have to call Invoke() of the Dispatcher of the control that you're trying to access , which in some cases may not be the same as System.Windows.Threading.Dispatcher.CurrentDispatcher . 关键是您必须Invoke() 要访问控件DispatcherInvoke() ,在某些情况下,它可能与System.Windows.Threading.Dispatcher.CurrentDispatcher So instead you should use YourControl.Dispatcher.Invoke() to be safe. 因此,相反,您应该使用YourControl.Dispatcher.Invoke()是安全的。 I was banging my head for a couple of hours before I realized this. 在意识到这一点之前,我敲了几个小时。

Update 更新资料

For future readers, it looks like this has changed in the newer versions of .NET (4.0 and above). 对于未来的读者来说,.NET的新版本(4.0及更高版本)似乎已发生了变化。 Now you no longer have to worry about the correct dispatcher when updating UI-backing properties in your VM. 现在,在更新VM中的UI支持属性时,您不再需要担心正确的调度程序。 WPF engine will marshal cross-thread calls on the correct UI thread. WPF引擎将在正确的UI线程上封送跨线程调用。 See more details here . 在这里查看更多详细信息。 Thanks to @aaronburro for the info and link. 感谢@aaronburro提供的信息和链接。 You may also want to read our conversation below in comments. 您可能还想阅读下面的评论我们的对话。


#6楼

If you encounter this problem and UI Controls were created on a separate worker thread when working with BitmapSource or ImageSource in WPF, call Freeze() method first before passing the BitmapSource or ImageSource as a parameter to any method. 如果您遇到此问题,并且在WPF中使用BitmapSourceImageSource单独的工作线程上创建了UI控件,请先调用Freeze()方法,然后再将BitmapSourceImageSource作为参数传递给任何方法。 Using Application.Current.Dispatcher.Invoke() does not work in such instances 在这种情况下,无法使用Application.Current.Dispatcher.Invoke()

展开阅读全文

Git 实用技巧

11-24
这几年越来越多的开发团队使用了Git,掌握Git的使用已经越来越重要,已经是一个开发者必备的一项技能;但很多人在刚开始学习Git的时候会遇到很多疑问,比如之前使用过SVN的开发者想不通Git提交代码为什么需要先commit然后再去push,而不是一条命令一次性搞定; 更多的开发者对Git已经入门,不过在遇到一些代码冲突、需要恢复Git代码时候就不知所措,这个时候哪些对 Git掌握得比较好的少数人,就像团队中的神一样,在队友遇到 Git 相关的问题的时候用各种流利的操作来帮助队友于水火。 我去年刚加入新团队,发现一些同事对Git的常规操作没太大问题,但对Git的理解还是比较生疏,比如说分支和分支之间的关联关系、合并代码时候的冲突解决、提交代码前未拉取新代码导致冲突问题的处理等,我在协助处理这些问题的时候也记录各种问题的解决办法,希望整理后通过教程帮助到更多对Git操作进阶的开发者。 本期教程学习方法分为“掌握基础——稳步进阶——熟悉协作”三个层次。从掌握基础的 Git的推送和拉取开始,以案例进行演示,分析每一个步骤的操作方式和原理,从理解Git 工具的操作到学会代码存储结构、演示不同场景下Git遇到问题的不同处理方案。循序渐进让同学们掌握Git工具在团队协作中的整体协作流程。 在教程中会通过大量案例进行分析,案例会模拟在工作中遇到的问题,从最基础的代码提交和拉取、代码冲突解决、代码仓库的数据维护、Git服务端搭建等。为了让同学们容易理解,对Git简单易懂,文章中详细记录了详细的操作步骤,提供大量演示截图和解析。在教程的最后部分,会从提升团队整体效率的角度对Git工具进行讲解,包括规范操作、Gitlab的搭建、钩子事件的应用等。 为了让同学们可以利用碎片化时间来灵活学习,在教程文章中大程度降低了上下文的依赖,让大家可以在工作之余进行学习与实战,并同时掌握里面涉及的Git不常见操作的相关知识,理解Git工具在工作遇到的问题解决思路和方法,相信一定会对大家的前端技能进阶大有帮助。
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值