此代码有什么问题或者可以更有效地完成吗?特别是,我有点担心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);
}
});
}
}
答案 0 :(得分:2)
特别是,我有点担心parrallel.foreach中的代码触发/调用委托。这可能导致任何问题吗?
一般而言,在Parallel.ForEach
方法中调用委托没有任何问题。
但是,它确实使控制线程安全性变得更加困难,因为委托将采用正确处理所有数据同步的要求。这主要是一个问题,因为使用委托的主要原因是允许传入您正在调用的“方法”,这意味着它是从外部提供的。
这意味着,例如,如果委托恰好调用尝试更新用户界面的代码,则可能会遇到麻烦,因为它将从后台/ ThreadPool线程调用。