异步更新对象在WPF列表框中显示时抛出异常

时间:2014-07-16 20:16:57

标签: c# wpf multithreading listbox

我目前正在编写更新List<>的WPF应用程序。来自网站的对象,并在列表框中显示这些对象。在同步更新这些对象时一切正常,当我尝试相同的操作但每个对象都在自己的线程中更新时会出现问题。以下是更新整个List<>的代码异步:

public void UpdateAll()
{
    Console.WriteLine("[Manager]Updating {0} channels", channels.Count);

    int threadCount = 0;

    for (int i = 0; i < channels.Count; i++)
    {
        int j = i;

        new System.Threading.Thread(() =>
            {
                threadCount++;
                channels[j].Update();
                threadCount--;
            }).Start();
    }

    while (threadCount != 0)
    {
        System.Threading.Thread.Sleep(10);
    }

    Console.WriteLine("[Manager]Updating complete");
}

更新完成后,我尝试在按钮的OnClick事件(应该是UI线程)中显示列表框中的对象:

private void button1_Click(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < manager.Channels.Count; i++)
    {
        channelBox.Items.Add(manager.Channels[i]);
    }
}

应用程序崩溃,给出了这个例外:

  

调用线程无法访问此对象,因为另一个线程拥有它。

在过去的几个小时里,我一直在谷歌搜索解决方案,但我发现只是在尝试从不同的线程更新UI时触发了这个异常。我确信所有更新线程已经完成,我认为没有理由抛出这个异常。我也尝试使用Dispacher.Invoke()方法更新列表框但没有成功,同样的异常。有什么帮助吗?

1 个答案:

答案 0 :(得分:-1)

可能有很多方法可以为这只猫提供皮肤......也许你可以通过在你的主要GUI线程中保留你的频道集合或包含它的类型来开始找到你正在做的事情的替代方案,同时包装你的.Update方法进入自己的调用(可能包括在更新时将项添加到列表框?)在包含集合的类型中,而不是作为通道类型本身成员的调用,并尝试调用它这样:

        if (Application.Current != null){
        Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
            UpdateChannel(channel[j])));}

Dispatcher.BeginInvoke允许Dispatcher在后台线程上操作或调用主GUI线程上的内容时对线程通信进行整理。