Как в пуле потоков проверить, что все фоновые потоки завершены, а после этого запускать уже другую задачу?
Здравствуйте, iumag, Вы писали:
I>Как в пуле потоков проверить, что все фоновые потоки завершены, а после этого запускать уже другую задачу?
1
в 4-м .NET
https://msdn.microsoft.com/ru-ru/library/system.threading.barrier%28v=vs.110%29.aspx
В терминах барьера у тебя всего один стейдж
2
в старом .net надо счетчик завести незавершенных
потоков задач и один ManualResetEvent
По окончании каждой задачи надо уменьшитть счетчик на еденицу и если он упал до нуля, то открываешь ManualResetEvent
Здравствуйте, iumag, Вы писали:
I>Как в пуле потоков проверить, что все фоновые потоки завершены, а после этого запускать уже другую задачу?
Решать задачу уровнем выше? Например организовать очередь заданий и по таймеру запускать параллельно выполняться N-ое количество из них.
| Простейший планировщик задач |
| class Job<TInput, TOutput>
{
private readonly TInput data;
private readonly TaskCompletionSource<TOutput> taskSource;
public Job(TInput data)
{
this.data = data;
this.taskSource = new TaskCompletionSource<TOutput>();
}
public Task<TOutput> Task
{
get
{
return this.taskSource.Task;
}
}
public async void RunAsync()
{
try
{
var result = await DoRealJobAsync(this.data);
this.taskSource.SetResult(result);
}
catch (OperationCanceledException)
{
this.taskSource.TrySetCanceled();
}
catch (Exception x)
{
this.taskSource.TrySetException(x);
}
}
private static async Task<TOutput> DoRealJobAsync(TInput data)
{
await ...
...
await ...
}
}
class JobScheduler<TInput, TOutput> : IDisposable
{
private readonly ConcurrentQueue<Job> jobQueue;
private readonly Timer timer;
private readonly TimeSpan runPeriod;
private readonly int numConcurrentJobs;
public JobScheduler(int numConcurrentJobs, TimeSpan runPeriod)
{
this.numConcurrentJobs = numConcurrentJobs;
this.runPeriod = runPeriod;
this.jobQueue = new ConcurrentQueue<Job>();
this.timer = new Timer(RunJobs);
this.timer.Change(TimeSpan.Zero, this.runPeriod);
}
public Task<TOutput> ScheduleJobAsync(TInput data)
{
var job = new Job<TInput, TOutput>(data);
this.jobQueue.Enqueue(job);
return job.Task;
}
public Dispose()
{
this.timer.Dispose();
}
private void RunJobs(object state)
{
for (var i = 0; i < this.numConcurrentJobs; ++i)
{
Job job;
if (this.jobQueue.TryDequeue(out job))
job.RunAsync();
}
}
}
|
| |