首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >BlockingCollection + UI线程

BlockingCollection + UI线程
EN

Stack Overflow用户
提问于 2010-10-19 20:06:36
回答 2查看 1.3K关注 0票数 3

我遵循了本教程,创建了一个优先级队列,并使用一个阻塞集合包装它。我有一个DataGrid,它连接到底层优先级队列,它会发出更改事件。我可以从UI线程w/out中将项添加到集合中,当缓冲区如预期的那样满时,它会阻塞。

现在我如何消费这些物品?我要说的是:

代码语言:javascript
运行
复制
public DownloadViewModel()
{
    Queue = new ConcurrentPriorityQueue<DownloadItem>(10);
    Buffer = new BlockingCollection<KeyValuePair<int, DownloadItem>>(Queue, 10000);

    Task.Factory.StartNew(() =>
    {
        KeyValuePair<int, DownloadItem> item;
        while(!Buffer.IsCompleted)
        {
            if(Buffer.TryTake(out item))
            {
                // do something with the item
            }

            Thread.SpinWait(100000);
        }
    });
}

但是,当我添加Task.Factory.StartNew位时,我的应用程序突然在窗口出现之前花了30秒(在窗口出现之前),当我添加了一个条目时,我就得到了异常。

这种类型的CollectionView不支持与Dispatcher线程不同的线程对其SourceCollection的更改。

我明白这一点,但是是否真的有必要使用UI线程来获取这些项呢?这难道不辜负使用这个BlockingCollection的全部目的吗?我想创建4或8个消费者,并让他们并行运行。

这该怎么做?

EN

回答 2

Stack Overflow用户

发布于 2010-10-19 21:25:28

包装CollectionChanged事件w/ a调度器似乎很好.

代码语言:javascript
运行
复制
public bool TryAdd(KeyValuePair<int, T> item)
{
    int pos = _queues.Take(item.Key + 1).Sum(q => q.Count);
    _queues[item.Key].Enqueue(item.Value);
    Interlocked.Increment(ref _count);
    Dispatcher.BeginInvoke(
        new Action(
            () =>
            NotifyCollectionChanged(
                new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, pos))
        ));
    return true;
}

我的ConcurrentPriorityQueue只需要从DispatcherObject那里得到。我想这就是该怎么做的。

更简单的是,只需编写如下的NotifyCollectionChanged方法:

代码语言:javascript
运行
复制
private void NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
{
    lock (CollectionChanged)
    {
        if (CollectionChanged != null)
            Dispatcher.BeginInvoke(new Action(() => CollectionChanged(this, e)));
    }
}

然后你就不用用BeginInvoke乱扔你的其他方法了。

票数 2
EN

Stack Overflow用户

发布于 2010-10-20 00:26:32

在就这个问题发表意见之后,

您不需要“使用UI线程获取项目”。但是,在处理消费任务中的项目时,对UI的任何更新都需要分派到UI线程。把你们的顾虑分开!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3972273

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档