c# async wait for event

thready
thready used Ask the Experts™
on
Hi Experts,

I'd like to write an async method that does this:

while(true) {
     
     await WaitForEventToBeSet(someEvent);  // someEvent auto-resets
     DoWork();
}


Somewhere else in the code:
someEvent.Set();

is this possible with async?  What class can I use?

Thanks a lot!
Mike
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
If I understand what you are trying to accomplish, it would just make more sense to use an AutoResetEvent (or even a Task with a cancellation token).

-saige-

Author

Commented:
Hi it_saige.  That's not really what I'm looking for.  The problem is that that will block.  I wanted to have something that I could await.  I think I'm diving a bit too deep on this one though.  Not sure this is possible.

If you've used async and await, think of it this way, I call some function that loops and waits on an event, but does so asynchronously.
Commented:
Describe your methodology here.  What are you trying to accomplish?

The purpose of async/await are to allow you to complete processes asynchrounously.  However, the result of the awaited method blocks it's current method until the awaited method returns its results (or throws an exception).

Proof of concept:
using System;
using System.Threading.Tasks;

namespace EE_Q28820699
{
	class Program
	{
		static void Main(string[] args)
		{
			Task task = new Task(ProcessLinesAsync);
			task.Start();
			task.Wait();
			Console.WriteLine("This line appears before all of the results are processed.");
			while (task.Status == TaskStatus.Running) { ;}
			Console.ReadLine();
		}

		static async void ProcessLinesAsync()
		{
			Console.WriteLine("Testing an awaited result");
			Task task = new Task(HaveSomeFun);
			task.Start();
			task.Wait();
			int x = await ProcessLines();
			Console.WriteLine("Processed {0} lines", x);
			Console.WriteLine("This line appears after the results are processed.");
			Console.WriteLine("Finished processing the task.  Press any key to exit.");
		}

		static async Task<int> ProcessLines()
		{
			int count = 0;
			for (int i = 0; i < 10; i++)
			{
				Console.WriteLine("Processing line {0}...", i);
				// Add a 5 second delay
				await Task.Delay(500);
				count++;
			}
			return count;
		}

		static async void HaveSomeFun()
		{
			for (int i = 0; i < 10; i++)
			{
				Console.WriteLine("Where's waldo? Checking position - {0}", i);
				// Add a 2.5 second delay
				await Task.Delay(250);
			}
		}
	}
}

Open in new window

If you run the above code you will get results similar to this -Capture.JPGJust by observing the output, we can see that the HaveSomeFun method ran asynchronously to the ProcessLinesAsync method (which itself ran asynchronously to the Main method).  And to your point, you are correct, none of this is blocking the main thread because if we were to press a key at any point the program would exit.  The only thing keeping the program alive at this moment is the Console.ReadLine() call which blocks the main thread.

However, we also notice that the following lines, appear only after the awaited result is returned:
'Processed 10 lines'
'This line appears after the results are processed'
and
'Finished processing the task.  Press any key to exit'

-saige-

Author

Commented:
Thanks a lot for your explanation.  

Sorry for taking so long to get back.  I had a broken project for a while after a nuget update...  

I wasn't awaiting the original call that calls this function.  So that one runs off seemingly on its own thread (but not).  I know there's never any other thread involved, but I was hoping somehow it would magically be able to wait for an event after "skipping over" the original call and getting to the stuff that will cause events to be set which would wake up my "thread" (without actually using a thread).  This will work if I don't block....  So I guess I could just put a wait with a timeout.  Would be totally cool to be able to do it with interrupts though.

Basically, the loop was just a provider that updates the UI asynchronously whenever events are fired off to it, and it also throttles how often it updates the UI by awaiting Task.Delay making sure a minimum time has passed before updating again...  But I guess I've answered my own question here with the wait with timeout...  Not what I was hoping for though.  Maybe you'll have something better for me?

Author

Commented:
Nope - I cannot do this because I'm eating away at processing time...  I guess I need a real thread unless you can see another way.  I've been kind of overdoing it with async and await because of the simplicity but maybe this is just getting silly.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial