繁体   English   中英

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

[英]Call an awaitable method inside a Thread in C#

在我的C#7.0代码中,我喜欢使用Thread类型的老式Thread做一些工作。 在此线程中,我需要使用一些异步方法。 调用这些方法的最佳方法是什么?

编写线程函数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();
        }
    }
}

如果我们往下调用堆栈,最终将有此调用:

// _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);

对于那些想知道为什么为什么要使用线程而不是任务的人:我想给它起一个有意义的名称以增强调试。 我没有找到命名任务的方法。 除此之外,此Thread的运行时间几乎与应用程序运行的时间一样,因此Thread对我而言确实有意义。

该线程几乎在应用程序运行的同时运行

不,不是。 因为它正在做的工作是异步的。 线程运行了足够长的时间以检查取消令牌的状态,触发ReadAsync (异步执行,基本上会立即返回),然后完成。 线程消失了,没有更多的工作要做。 这就是异步操作的全部思想。 异步意味着操作几乎立即返回到其调用者,并且将控制权返回给调用者之后会执行其有意义的工作(在这种情况下,由于这是线程的顶级方法,因此将控制权返回意味着线程执行完毕并被拆除)。

因此,创建新线程只是为了让它检查一个布尔值并启动一些将自行运行的操作而已,并没有太多目的。 不是说您应该使用其他方法来使新线程工作(例如使用Task.Run ),而是您不应使用任何方法来使新线程工作,因为您没有任何方法。长时间运行的CPU要做的工作。 您已经进行了长时间运行(从外观上看,它不受CPU限制)已经是异步的 ,因此您可以直接从想要启动该工作的任何线程中直接调用该方法,并使其正确执行。

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

暂无
暂无

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

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