Yasser Shaikh
Yasser Shaikh

Reputation: 47784

How to run multiple tasks in c# and get an event on complete of these tasks?

I am re-running a Task when its completed. Below is the function I call in the Application_Start of my application.

private void Run()
{
    Task t = new Task(() => new XyzServices().ProcessXyz());
    t.Start();
    t.ContinueWith((x) =>
    {
        Thread.Sleep(ConfigReader.CronReRunTimeInSeconds);
        Run();
    });
}

I want to run multiple tasks, number which will be read from web.config app setttings.

I am trying something like this,

private void Run()
{
    List<Task> tasks = new List<Task>();
    for (int i = 0; i < ConfigReader.ThreadCount - 1; i++)
    {
        tasks.Add(Task.Run(() => new XyzServices().ProcessXyz()));
    }

    Task.WhenAll(tasks);

    Run();
}

Whats the correct way to do this ?

Upvotes: 10

Views: 18067

Answers (3)

Jodrell
Jodrell

Reputation: 35716

if you want to run the tasks one after the other,

await Task.Run(() => new XyzServices().ProcessXyz());
await Task.Delay(ConfigReader.CronReRunTimeInSeconds * 1000);

if you want to run them concurrently, as the task scheduler permits,

await Task.WhenAll(new[]
    {
        Task.Run(() => new XyzServices().ProcessXyz()),
        Task.Run(() => new XyzServices().ProcessXyz())
    });

So, your method should be something like,

private async Task Run()
{
    var tasks =
        Enumerable.Range(0, ConfigReader.ThreadCount)
        .Select(i => Task.Run(() => new XyzServices().ProcessXyz()));

    await Task.WhenAll(tasks); 
}

Upvotes: 9

EZI
EZI

Reputation: 15364

If you want to wait all tasks to finish and then restart them, Marks's answer is correct.

But if you want ThreadCount tasks to be running at any time (start a new task as soon as any one of them ends), then

void Run()
{
    SemaphoreSlim sem = new SemaphoreSlim(ConfigReader.ThreadCount);

    Task.Run(() =>
    {
        while (true)
        {
            sem.Wait();
            Task.Run(() => { /*Your work*/  })
                .ContinueWith((t) => { sem.Release(); });
        }
    });
}

Upvotes: 1

Mark Jansen
Mark Jansen

Reputation: 1509

I believe you are looking for:

Task.WaitAll(tasks.ToArray());

https://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx

Upvotes: 13

Related Questions