简体   繁体   English

在C#中的线程中调用等待的方法

[英]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. 在我的C#7.0代码中,我喜欢使用Thread类型的老式Thread做一些工作。 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. 编写线程函数async没有任何意义。

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. 除此之外,此Thread的运行时间几乎与应用程序运行的时间一样,因此Thread对我而言确实有意义。

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. 线程运行了足够长的时间以检查取消令牌的状态,触发ReadAsync (异步执行,基本上会立即返回),然后完成。 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. 不是说您应该使用其他方法来使新线程工作(例如使用Task.Run ),而是您不应使用任何方法来使新线程工作,因为您没有任何方法。长时间运行的CPU要做的工作。 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. 您已经进行了长时间运行(从外观上看,它不受CPU限制)已经是异步的 ,因此您可以直接从想要启动该工作的任何线程中直接调用该方法,并使其正确执行。

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 . 如果您只是想拥有一些可以在异步操作的逻辑调用上下文中共享的值,那么当然可以使用一些工具来实现这一点,例如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. 创建一个新线程将无法完成该任务,因为当您完成启动异步操作时,您的线程已经死了,而且继续运行的线程仍然会在其他线程中运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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