我知道网站上已经多次询问过这个问题,但是我已经尝试按照给出的建议,但我无处可去。
我有一个从单独的线程调用的方法,它只是将一个TextBlock添加到GUI上的stackpanel。但无论我如何尝试实现这一点,我都会收到错误:“调用线程无法访问此对象,因为另一个线程拥有它”
道歉,如果这是一个非常简单的问题,但我对WPF来说是全新的......
private void AddTbToStackPanel(string text)
{
StackPanel stackPanel = stackPanel1 as StackPanel;
TextBlock tb = new TextBlock();
tb.Text = text;
stackPanel.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => { stackPanel.Children.Add(tb); }));
}
答案 0 :(得分:4)
您正在工作线程中创建文本块。
将new TextBlock()
移动到lambda。
stackPanel.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
() => { stackPanel.Children.Add(new TextBlock { Text = text }); }));
答案 1 :(得分:3)
刚想通了 - 我需要在所有对象上使用Dispatcher,如下所示:
private void AddTbToStackPanel(string text)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{
StackPanel stackPanel = stackPanel1 as StackPanel;
TextBlock tb = new TextBlock();
tb.Text = text;
stackPanel.Children.Add(tb);
}));
}
答案 2 :(得分:1)
private void AddTbToStackPanel(string text)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => {
StackPanel stackPanel = stackPanel1 as StackPanel;
TextBlock tb = new TextBlock();
tb.Text = text;
stackPanel.Children.Add(tb);
}));
}
答案 3 :(得分:0)
以下示例可帮助您实现任务和UI更新。您可以轻松地将以下示例转换为您的方案。 您可以查看我的博客,其中包含有关此错误和解决方案的详细说明
http://bathinenivenkatesh.blogspot.com/2011/07/wpf-build-more-responsive-ui.html
ObservableCollection images = new ObservableCollection();
TaskFactory tFactory = new TaskFactory();
tFactory.StartNew(() =>
{
for (int i = 0; i < 50; i++)
{
//GET IMAGE Path FROM SERVER
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
// UPDATE PROGRESS BAR IN UI
});
images.Add(("");
}
}).ContinueWith(t =>
{
if (t.IsFaulted)
{
// EXCEPTION IF THREAD IS FAULT
throw t.Exception;
}
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
//PROCESS IMAGES AND DISPLAY
});
});