在BackgroundWorker中出现“UnauthorizedAccessException”但没有访问UI线程

5
我正在使用BackgroundWorker进行一些繁重的工作,以便不影响我的Silverlight UI线程。但是,在DoWork函数中,我遇到了以下异常:
UnauthorizedAccessException "无效的跨线程访问"。
我知道不能从BackgroundWorker访问UI线程,但是这个异常在这一行发生:
  ListBoxItem insert = new ListBoxItem();

你是如何访问我的UI线程的??

这是我缩小范围后的实际代码段。我基本上正在创建listboxitems,希望将其插入到sourceList列表框中:

void FillSourceList()
{
    busyIndicator.IsBusy = true;
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += (sender, args) =>
        {
            List<ListBoxItem> x = new List<ListBoxItem>();
            for (int i = 0; i < 25; i++ )
            {
                ListBoxItem insert = new ListBoxItem(); //<---Getting exception here
                insert.Content = "whatever";
                x.Add(insert);
            }
            args.Result = x;
        };
    bw.RunWorkerCompleted += (sender, args) =>
        {
            foreach (ListBoxItem insert in (List<ListBoxItem>)(args.Result))
                sourceList.Items.Add(insert);
            busyIndicator.IsBusy = false;
        };

    bw.RunWorkerAsync();
}
1个回答

4

ListBoxitem是从Control派生而来的,因此被认为是GUI的一部分。我本以为“分离”的项在线程中也可以正常工作,但显然并非如此。

明显的解决方案:建立一个Content(字符串)列表x,并延迟Items的创建直到Completed事件发生。


谢谢。是的,似乎这样做有点不必要,但仍然很有趣。我对ListBoxItem进行了一些其他处理,基于内容进行着色,因此我不能简单地创建字符串..但是,我想我会将所需信息打包到KeyValuePair或其他东西中,直到它们被创建。 - David S.
你可以考虑为这些项使用一个小型的ViewModel。只需将列表绑定到ItemsSource,就可以完成设置,包括线程安全。 - H H
好主意!我可能会这样做,希望不需要太多更改来完成项目的其余部分(希望如此;)。 - David S.
@HenkHolterman 我认为只要列表通过ItemsSource绑定到控件,修改列表仍然会导致“无效的跨线程访问”,一旦数据绑定将更改传播到控件。您确定这样可以解决问题吗? - Oliver Weichhold
@OliverWeichhold - Completed事件在GUI线程上运行。 - H H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接