调用线程无法访问此对象错误

时间:2013-07-02 10:14:57

标签: c# wpf multithreading

我正在尝试在后台线程中动态创建自定义userControl。 这是我创建新线程的方法:

var thread = new Thread(CreateItemInBackgroundThread);
thread.SetApartmentState(ApartmentState.STA);            
thread.Start();
thread.Join();

这是方法CreateItemInBackgroundThread

var uc = new MyUserControl();
UserControl item = uc;
AllControls.Add(item);
//Here I am trying to add control to a current Tab
foreach (var currentTab in _allTabs)
{
    currentTab.DocumentWindow.Dispatcher.BeginInvoke(new Action(() =>
                                                            {
                                                                if (tab.DocumentWindow.IsSelected)
                                                                {
                                                                    tempTab = tab;
                                                                    tempControl = item;
                                                                    finish = true;
                                                                }

                                                            }));
}

这是我的完成属性

bool finish
    {
        get { return _finish; }
        set
        {
            _finish = value;
            if (_finish)
            {
                tempTab.AnimatedCanvas.Dispatcher.BeginInvoke(new Action(() => tempTab.AnimatedCanvas.Children.Add(tempControl)));
            }
        } // Here I get error - The calling thread cannot access this object because a different thread owns it
    }

如何避免此错误以及发生此错误的原因?

2 个答案:

答案 0 :(得分:0)

如错误所示,您无法访问此对象,因为另一个线程拥有它,因此您可以使用Invoke(Delegate Method)调用该线程 您可以使用tempTab.InvokeRequired

检查是否需要调用

答案 1 :(得分:0)

此错误即将发生,因为您必须在同一个线程上执行不同的任务,例如U无法使线程变为异步并使用相同的线程更新UI。这将导致冲突。因为UI线程是主线程。< / p>

你可以使用BAckground Worker Thread并将它的两个eventHandler加入到你想要处理的事件中......例如 -

BackgroundWorker Worker=new BackgroundWorker();
worker.DoWork+=Yorevent which will do the timeTaking Task();
Worker.RunWorkerCompleted+=YOurEvent which will Update your UI after the work is done();
worker.RunWorkerAsync();

RunWorkerAsync()将使您的线程变为异步并在后台工作 这样它也不会导致任何线程错误..