2

这段代码有什么问题还是可以更有效地完成?特别是,我有点担心 parrallel.foreach 中的代码触发/调用委托。这可能会导致任何问题吗?我问是因为目前消费者在很多情况下无法跟上正在生产的物品,导致记忆问题。

public delegate void DataChangedDelegate(DataItem obj);

public class Consumer
{
    public DataChangedDelegate OnCustomerChanged;
    public DataChangedDelegate OnOrdersChanged;

    private CancellationTokenSource cts;
    private CancellationToken ct;
    private BlockingCollection<DataItem> queue;

    public Consumer(BlockingCollection<DataItem> queue) {
        this.queue = queue;
        Start();
    }

    private void Start() {
        cts = new CancellationTokenSource();
        ct = cts.Token;
        Task.Factory.StartNew(() => DoWork(), ct);
    }

    private void DoWork() {

        Parallel.ForEach(queue.GetConsumingPartitioner(), item => {
            if (item.DataType == DataTypes.Customer) {
                OnCustomerChanged(item);
            } else if(item.DataType == DataTypes.Order) {
                OnOrdersChanged(item);
            }
        });
    }
}
4

1 回答 1

2

特别是,我有点担心 parrallel.foreach 中的代码触发/调用委托。这可能会导致任何问题吗?

一般来说,从Parallel.ForEach方法中调用委托并没有错。

但是,它确实使控制线程安全变得更加困难,因为委托将承担正确处理所有数据同步的要求。这主要是一个问题,因为使用委托的主要原因是允许传入您调用的“方法”,这意味着它是由外部提供的。

这意味着,例如,如果委托碰巧调用了尝试更新用户界面的代码,您可能会遇到麻烦,因为它将从后台/线程池线程中调用。

于 2012-06-21T00:32:46.017 回答