-2

I am trying to start a count and then another method will stop this counting by generating a random number between 1 and 6 seconds. I can do the counting but stopper function did not start asynchronously with my Count function. I want both of them to sart at the same time so I put two await statements inside same DoAsync method. But it does not work as intended because random number is generated at the end of counting. I need the generation start at the beginning of the count...

The output is like this:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 In2126 milliseconds: count will stop...

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication
{
class Program
{
    static void Main(string[] args)
    {
        CancellationTokenSource ctSource = new CancellationTokenSource();
        CancellationToken ctToken = ctSource.Token;

        Task t1 = DoAsync(ctSource, ctToken);

        t1.Wait();
    }

    private static async Task DoAsync(CancellationTokenSource ctSource, CancellationToken ctoken)
    {
        if (ctoken.IsCancellationRequested)
            return;

        await Task.Run(() => Count(ctoken), ctoken);
        await Task.Run(() => Stop(ctSource), ctoken);
    }

    public static void Count(CancellationToken ctoken)
    {
        for (int i = 0; i < 20; i++)
        {
            if (ctoken.IsCancellationRequested)
            {
                Console.WriteLine("stopped at :" + i);

                break;
            }
            else
            {
                Console.WriteLine(i);
                Thread.Sleep(150);
            }
        }
    }

    public static void Stop(CancellationTokenSource cSource)
    {
        Random r = new Random();
        int milliseconds = r.Next(1000, 6000);
        Console.WriteLine("In" + milliseconds + "  milliseconds: " + "count will stop...");

        Thread.Sleep(milliseconds);
        cSource.Cancel();
    }

}

}

Lyrk
  • 1,936
  • 4
  • 26
  • 48
  • 1
    _" I want both of them to sart at the same time so I put two await statements inside same DoAsync method"_ -- the `await` doesn't start the task, it interrupts execution of the method until the task has _completed_. Thus, your code specifically waits until the first task has completed before starting the second. You want to start both and _then_ `await WhenAll()` where you pass the task objects (saved in local variables) from the two `Task.Run()` method calls. See marked duplicate for additional details. – Peter Duniho Nov 14 '17 at 09:00

1 Answers1

2

You can use Task.WhenAll() for this purpose. It takes an array of tasks and creates a new task that will finish when all source tasks are finished.

var taskCount = Task.Run(() => Count(ctoken), ctoken);
var taskStop = Task.Run(() => Stop(ctSource), ctoken);
await Task.WhenAll(new [] { taskCount, taskStop });
CodeFuller
  • 30,317
  • 3
  • 63
  • 79