我目前正在开发一个项目,我需要将一些作业排队进行处理,这是要求:
- 作业必须一次处理一个
- 排队的项目必须能够等待
所以我想要类似的东西:
Task<result> QueueJob(params here)
{
/// Queue the job and somehow return a waitable task that will wait until the queued job has been executed and return the result.
}
我尝试过让后台运行任务仅从队列中取出项目并处理作业,但困难在于从后台任务到该方法。
如果需要的话,我可以选择在 QueueJob 方法中请求完成回调的路线,但是如果我可以获得一个透明的任务,允许您等待要处理的作业(即使有作业),那就太好了在队列中的前面)。
你可能会发现TaskCompletionSource<T>很有用,它可以用来创建一个Task
它会在您想要的时候完全完成。如果你把它与BlockingCollection<T>
,你会得到你的队列:
class JobProcessor<TInput, TOutput> : IDisposable
{
private readonly Func<TInput, TOutput> m_transform;
// or a custom type instead of Tuple
private readonly
BlockingCollection<Tuple<TInput, TaskCompletionSource<TOutput>>>
m_queue =
new BlockingCollection<Tuple<TInput, TaskCompletionSource<TOutput>>>();
public JobProcessor(Func<TInput, TOutput> transform)
{
m_transform = transform;
Task.Factory.StartNew(ProcessQueue, TaskCreationOptions.LongRunning);
}
private void ProcessQueue()
{
Tuple<TInput, TaskCompletionSource<TOutput>> tuple;
while (m_queue.TryTake(out tuple, Timeout.Infinite))
{
var input = tuple.Item1;
var tcs = tuple.Item2;
try
{
tcs.SetResult(m_transform(input));
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}
}
public Task<TOutput> QueueJob(TInput input)
{
var tcs = new TaskCompletionSource<TOutput>();
m_queue.Add(Tuple.Create(input, tcs));
return tcs.Task;
}
public void Dispose()
{
m_queue.CompleteAdding();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)