简体   繁体   中英

Call an awaitable method inside a Thread in C#

In my C# 7.0 Code I like to use an old school Thread of type Thread to do some work. Inside this Thread, I need to use some async methods. What would be the best approach to call these methods?

Writing the thread function async does not make any sense.

this._networkListenerThread = new Thread(/* async here is not an option */() =>
{
    while (!this._listenerCancellation.IsCancellationRequested)
    {
        try
        {
            //  This does not compile
            var packetBuffer = await this._commProxy.ReadAsync();

            doSomethingMore();
        }
    }
}

If we go down the call stack, finally there will be this call:

// _socket is of type Android.Bluetooth.BluetoothSocket
// .InputStream of type System.IO.Stream
// ReadAsync only returns when data arrived on the stream 
// or throws an exception when the connection is lost
var receivedBytes = await this._socket.InputStream.ReadAsync(buffer, 0, buffer.Length);

For those wondering why I want to use a Thread instead of Task: I want to give it a meaningful name to enhance debugging. I did not find a way to name a Task. Besides of this, this Thread runs almost as long as the application runs, therefore a Thread does make sense for me.

this Thread runs almost as long as the application runs

No, it doesn't. Because the work that it's doing is asynchronous. The thread runs long enough to check the status of the cancellation token, fire off ReadAsync (which, being asynchronous, will return basically immediately) and then it's done. The thread goes away, and it has no more work to do. That's the whole idea of asynchronous operations; being asynchronous means the operation returns to its caller pretty much immediately, and does whatever meaningful work it has to do after returning control back to the caller (in this case, since this is the top level method of the thread, returning control back means that the thread has finished executing and gets torn down).

So there just isn't much of any purpose in creating a new thread just to have it check a boolean value and start some operation that will go off and do work on its own. It's not that you should use a different way of getting a new thread to do work (like using Task.Run ), but rather you shouldn't use any means of getting a new thread to do work, because you don't have any long running CPU bound work to do. The long running (non-CPU bound, by the look of it) work that you have is already asynchronous , so you can just call the method directly from whatever thread wants to start this work, and have it do it right in line.

If you simply want to have some value that you can share along an asynchronous operation's logical call context, there are of course tools that accomplish that, such as AsyncLocal . Creating a new thread wouldn't accomplish that, because as you finish starting the asynchronous operation you have your thread is dead and gone, and the continuations will be running in some other thread anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM