It is not pretty, but you could wrap this inside a BackgroundWorker or other threading technique.
I do not know what your BlockingCollection is, but I will assume for the sake of the code below that it consists of a BlockingItem Collection.
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();
}
}
Your BackgroundWorker's DoWork method is not going to take up any CPU resources while it is waiting for the next BlockingItem to be released.
The variable I defined _someExternalFlag
could be anything that is set when a user clicks a Cancel Button or set when the Form is closed.