KansaiRobot
KansaiRobot

Reputation: 9912

Using a timer to wait for processes to complete

Imagine there are two buttons that call an asynchronous function

  int packProcesses=0;  //the number of processes we are dealing with
    bool busy = false;  //are we busy?
   int v=10;
  private async void button5_Click(object sender, EventArgs e)
  {
    packProcesses++;
    busy = true;
    Trace.WriteLine("PROCESSES " + packProcesses + " busy? " + busy);
    //Do something
    var result = await DelayAndReturnAsync(v);
    //finished?
    packProcesses--;
    if (packProcesses <= 0) busy = false;
    Trace.WriteLine("Processes " + packProcesses + " busy? " + busy);
    }

    private async void button6_Click(object sender, EventArgs e)
     {
       packProcesses++;
       busy = true;
       Trace.WriteLine("PROCESSES " + packProcesses + " busy? " + busy);

        //Do something
        var result = await DelayAndReturnAsync(v);
        //finished?
        packProcesses--;
        if (packProcesses <= 0) busy = false;
        Trace.WriteLine("Processes " + packProcesses + " busy? " + busy);
        }

Where the asynchronous function is

 async Task<int>DelayAndReturnAsync(int val)
  {
   await Task.Delay(TimeSpan.FromSeconds(val)).ConfigureAwait(false);
   Trace.WriteLine("Time" + DateTime.Now);
    return val;
   }

and I want to have another button that calls both of the buttons. If I just put both click functions one after another I will have both processes started at once.

Since I want one processes to start after the other I do

 private async void button8_Click(object sender, EventArgs e)
  {
  button5_Click(sender, e);
   do
    {
     await Task.Delay(1000);
     } while (busy);
    button6_Click(sender, e);
    }

I took the idea from this answer

Is this a good idea? I don't want to clog the CPU in order to do this. Is there a better way to wait for one process to complete to start the other?

Upvotes: -1

Views: 250

Answers (2)

Alessandro D&#39;Andria
Alessandro D&#39;Andria

Reputation: 8868

You can move your logic from inside the handler to another method:

private async void button1_Click(object sender, EventArgs e)
{
    await Process1();
}

private async Task Process1()
{
    packProcesses++;
    busy = true;
    Trace.WriteLine("PROCESSES " + packProcesses + " busy? " + busy);
    //Do something
    var result = await DelayAndReturnAsync(v);
    //finished?
    packProcesses--;
    if (packProcesses <= 0) busy = false;
    Trace.WriteLine("Processes " + packProcesses + " busy? " + busy);
}

private async void button2_Click(object sender, EventArgs e)
{
    await Process2();
}

private async Task Process2()
{
    packProcesses++;
    busy = true;
    Trace.WriteLine("PROCESSES " + packProcesses + " busy? " + busy);

    //Do something
    var result = await DelayAndReturnAsync(v);
    //finished?
    packProcesses--;
    if (packProcesses <= 0) busy = false;
    Trace.WriteLine("Processes " + packProcesses + " busy? " + busy);
}

Then you can await both them:

private async void button3_Click(object sender, EventArgs e)
{
    await Process1();
    await Process2();
}

Upvotes: 2

Dan Scott
Dan Scott

Reputation: 564

if you can at all, I would try and avoid having your button6_Click and button5_Click methods returning void. if instead you have them return a Task you can await them.

private async Task button5_Click(object sender, EventArgs e) 
{ ... }

private async Task button8_Click(object sender, EventArgs e) 
{
     await button5_Click(sender, e);
     await button6_Click(sender, e);
}

edit:

private async Task HandleButton5_Click() 
{
     ...
}    

private async void button5_Click(object sender, EventArgs e) 
{  
    await HandleButton5_Click();
}

private async void button8_Click(object sender, EventArgs e) 
{
     button5_Click(sender, e);
     button6_Click(sender, e);
}

Upvotes: 2

Related Questions