如果您使用的是 .NET 4.0 或更高版本,我建议直接使用 TPL 而不是线程,并且我建议使用 aBlockingCollection<T>
作为 UI 可以通过集合“提供一些工作”供消费者执行的方式。
然后,消费者可以是一个长期运行的Task
(同样来自 TPL),BlockingCollection<T>
从BlockingCollection<T>
.时间,然后在项目准备好使用时恢复。
因此,您可以将取消令牌源、阻塞集合和任务定义为:
private BlockingCollection<Transaction> _bin = new BlockingCollection<Transaction>();
private CancellationTokenSource _tokenSource = new CancellationTokenSource();
private Task _consumer;
您的消费者方法可以定义为:
private void ConsumeTransactions()
{
// loop until consumer marked completed, or cancellation token set
while (!_bin.IsCompleted && !_tokenSource.Token.IsCancelRequested)
{
Transaction item;
// try to take item for 100 ms, or until cancelled
if (_bin.TryTake(out item, 100, _tokenSource.Token)
{
// consume the item
}
}
}
然后,当您的表单加载时,您将通过执行以下操作来启动任务:
// when you have a task running for life of your program, make sure you
// use TaskCreationOptions.LongRunning. This typically sets up its own
// dedicated thread (not pooled) without having to deal with threads directly
_consumer = Task.Factory.StartNew(ConsumeTransactions, _tokenSource.Token,
TaskCreationOptions.LongRunning, TaskScheduler.Default);
然后通过执行添加项目:
_bin.TryAdd(someTransaction);
Transaction
无论您定义要执行的工作单元在哪里...
最后,当您的应用程序想要关闭时,它可以执行以下操作:
_bin.CompleteAdding();
这告诉消费者不会再将任何项目添加到队列中,这将使TryTake()
return false
,并退出循环,因为那时_bin.IsCompleted
将是true
。
然后,您的长时间运行的任务可以在阻塞获取上循环,直到设置取消令牌(也是 TPL)以告诉它关闭...