1

I have a project to submit job to AWS state machine and monitor the job status. So I implement the code like following pseudo code:

Two tasks are calling in the main function:

       public static void Main(string[] args)
        {
            ExeJobs("1").Wait();
            MonitorJobs().Wait();
        }

In MonitoryJobs task, do something like:

        public static async Task MonitorJobs()
        {
            int retry = 0;

            for (int i = 0; i < retry; i++)
            { 
                // Check History event here if find job id. else keep looping;
                ....
            }
        }

In ExeJobs task, do something like:

       public static async Task ExeJobs(string jobId)
        {
            await SubmitJob(jobId);

            ExecutionStatus status = ExecutionStatus.RUNNING;

            while (status == ExecutionStatus.RUNNING)
            {
                status = await MonitorJobStaus(jobId);
            }
        }

I expected the MonitorJobs() is a thread keep live till I find the job execute status when it's running ExeJobs(). However it looks the MonitorJobs() task cannot start before ExeJobs() finish its while(status == ExecutionStatus.RUNNING) loop.

I wish MonitorJobs() can be running during the while loop in the other task and it should be expected result since they are two threads.

Anyone knows what's wrong here? Thanks

stuartd
  • 70,509
  • 14
  • 132
  • 163
deritha
  • 13
  • 4
  • First, you mark `MonitorJobs` as `async`, but you don't `await` anything in the code you show. I expect you get a warning about this. I don't see anything that creates or starts a thread. Why do you expect things to be running on multiple threads – Flydog57 Aug 20 '20 at 22:33
  • 1
    _they are two threads_ - what makes you think that? Just because something is `async` that doesn't mean you get two threads. Also, can't you make your `Main` method `async` so you don't have to call `Wait()` synchronously? – stuartd Aug 20 '20 at 22:33

3 Answers3

4

Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete. As a general rule, you should use "async all the way down"; that is, don't block on async code.

   public static async Task Main(string[] args)
    {
        await ExeJobs("1");
        await MonitorJobs();
    }
Bruce Adams
  • 12,040
  • 6
  • 28
  • 37
1

Wait will block until the task is finished. Also How your program will behave will be depended on what actually is happening inside your async tasks. You can use Task.WhenAll (making your main method async):

public static async Task Main(string[] args)
{
    await Task.WhenAll(ExeJobs, MonitorJobs);
}

This will start both tasks (assuming that ExeJobs is actually asynchronous) and wait until both finish.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
1

So you need to understand that when you await something, execution in that scope stops until the task is completed. If you want to have the execution keep going without waiting for it to finish, you need to assign it to a task and you can wait for it to finish after.

public static async Task Main(string[] args)
{
    // start ExeJobs task but don't wait for it to finish
    var jobTasks = ExeJobs("1");

    // start monitor task but don't wait for it to finish
    var monitorTask = MonitorJobs();

    // wait for both tasks to finish before returning
    await Task.WhenAll(jobTasks, monitorTask);
}
Todd Skelton
  • 6,839
  • 3
  • 36
  • 48