2

このコードに何か問題がありますか、それともより効率的に行うことができますか? 特に、parallel.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

特に、parallel.foreach 内のデリゲートの起動/呼び出し内のコードについて少し心配しています。これは潜在的に問題を引き起こす可能性がありますか?

Parallel.ForEach一般的に言えば、メソッド内からデリゲートを呼び出すことに問題はありません。

ただし、デリゲートはすべてのデータ同期を正しく処理するための要件を引き受けるため、スレッド セーフの制御がより困難になります。デリゲートを使用する主な理由は、呼び出している「メソッド」が渡されることを許可することであるため、これは主に問題です。これは、外部から提供されることを意味します。

これは、たとえば、デリゲートがユーザー インターフェイスを更新しようとするコードを呼び出した場合、バックグラウンド/ThreadPool スレッドから呼び出されるため、問題が発生する可能性があることを意味します。

于 2012-06-21T00:32:46.017 に答える