Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to use "async" with a ThreadStart method?

Tags:

c#

async-await

I have a Windows Service that uses Thread and SemaphoreSlim to perform some "work" every 60 seconds.

class Daemon
{
    private SemaphoreSlim _semaphore;
    private Thread _thread;

    public void Stop()
    {
        _semaphore.Release();
        _thread.Join();
    }

    public void Start()
    {
        _semaphore = new SemaphoreSlim(0);
        _thread = new Thread(DoWork);
        _thread.Start();
    }

    private void DoWork()
    {
        while (true)
        {
            // Do some work here

            // Wait for 60 seconds, or exit if the Semaphore is released
            if (_semaphore.Wait(60 * 1000))                
            {
                return;
            }
        }
    }
}

I'd like to call an asynchronous method from DoWork. In order to use the await keyword I must add async to DoWork:

private async void DoWork()
  1. Is there any reason not to do this?
  2. Is DoWork actually able to run asynchronously, if it's already running inside a dedicated thread?
like image 799
James Avatar asked Jun 05 '17 07:06

James


People also ask

Should I add async to method name?

You should add suffix Async to a method which, in some cases (not necessarily all), doesn't return a value but rather returns a wrapper around an ongoing operation.

Should every method be async?

If a method has no async operations inside it there's no benefit in making it async . You should only have async methods where you have an async operation (I/O, DB, etc.). If your application has a lot of these I/O methods and they spread throughout your code base, that's not a bad thing.

Is async multi threading?

Async programming is about non-blocking execution between functions, and we can apply async with single-threaded or multithreaded programming. So, multithreading is one form of asynchronous programming.

What happens if we execute an asynchronous method but don't await it?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.


1 Answers

You can do this, but it wouldn't be a good idea. As soon as the first await hits that is not synchronously completed, the rest of the work will be done on a continuation, not the thread you started (_thread); the thread you start will terminate at the first such await. There is no guarantee that a continuation will go back to the originating thread, and in your scenario, it cannot - that thread is now toast. That means that:

  1. _thread is meaningless and does not represent the state of the operation; as such, your Stop() method with a _thread.Join(); doesn't do what you expect it to do
  2. you've created a thread (allocating threads is expensive, in particular because of the size of the stack) only to have it exit almost immediately

Both of these issues can avoided by using Task.Run to start such operations.

like image 86
Marc Gravell Avatar answered Sep 23 '22 07:09

Marc Gravell