これはかなりありませんが、BackgroundWorkerまたは他のスレッド技法の中でこれを囲むことができます。
私はあなたのBlockingCollectionがあるが、私はそれがBlockingItemコレクションで構成されていることを以下のコードのために前提となるかわかりません。
private bool _someExternalFlag;
private void Test(BlockingCollection items)
{
_someExternalFlag = false;
using (var worker = new BackgroundWorker())
{
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += delegate
{
var index = 0;
foreach (var item in items)
{
if (worker.CancellationPending)
{
break;
}
index++;
// ... process your item here or by passing it to the main thread
worker.ReportProgress(index, item);
}
};
worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e)
{
if (_someExternalFlag)
{
worker.CancelAsync();
}
else
{
var item = e.UserState as BlockingItem;
// use item if you need it
}
};
worker.RunWorkerAsync();
}
}
はあなたのBackgroundWorkerのDoWorkメソッドは、解放される次のBlockingItemを待っている間に任意のCPUリソースを占有するつもりはありません。
変数Iが_someExternalFlag
と定義されている場合は、ユーザーがキャンセルボタンをクリックするか、フォームが閉じられたときに設定されるものであれば何でも構いません。
http://stackoverflow.com/q/23295119/11683 – GSerg
の複製でもそうでなくてもかまいません。「列挙を停止する」という意味を明確にするのに役立つと思います。コードは停止しているので、次の項目をブロックして、スレッドのブロックされた列挙を別のスレッドから取り消すことについて話していると仮定できます。それとも、他に何か覚えていますか? – 31eee384
ライブラリを使うと書いているので、コードの 'items'部分の実装を制御できないと思います。その場合、私はエレガントなオプションがあるとは思わない。ラグを下に引き出すことができる別のインダイレクション層を追加する以外に、最善のケースのシナリオではぎこちなく、非常に危険です。スレッドを終了すると危険です。オプションは非常に限られています。 –