在一种方法上同时使用等待/异步和线程是不是可行?

Posted

技术标签:

【中文标题】在一种方法上同时使用等待/异步和线程是不是可行?【英文标题】:Is it viable to use await/async and threads simultaneously on one method?在一种方法上同时使用等待/异步和线程是否可行? 【发布时间】:2018-02-05 13:16:39 【问题描述】:

我是多线程新手,我有一个(可能)关于同时使用线程和等待/异步的简单问题。我有一个方法可以读取 TCP 流,然后处理它收到的响应。它的调用方式如下所示:

ThreadStart ts = new ThreadStart(ReadTCP);
Thread tt = new Thread(ts);

从流中异步读取数据是否可行?就像在这段代码中一样:

    private async void ReadTCP()
    
        string responseData = string.Empty;  

        if(streamTCP.DataAvailable) 
        
            responseData = await  readerTCP.ReadToEndAsync();

            // some code handling the response
        
    

使用MarioDS's help编辑的代码

【问题讨论】:

我不认为你的 streamTCP 是线程安全的。此代码会以某种方式失败。 我还没锁,但我知道怎么做。 锁定可能会使您尝试执行的任何线程无效。 这是关于异步 I/O 的。你不需要线程。你不想要线程。你当然不应该使用async void 方法。 【参考方案1】:

手动创建和操作线程是一种高级多线程技术,需要开发人员真正知道他在做什么(因为内存隔离、线程之间的同步和编组都是非常高级的主题,而且很容易搞砸了)。线程安全很难。

如果您只想提高应用程序的响应能力,那么几年前添加到 .NET 中的 async 和 await 构造是完美的。它们不一定与多线程相关,因为它是决定是否创建新线程的底层机制(并非总是如此)。

您正在做的是创建一个线程并在该线程上运行ReadTCP 方法。

您可以轻松修复ReadTCP,使其返回Taskasync void 是非常糟糕的做法!)然后像这样使用它:var response = await ReadTCP();async 方法中,它会给你什么你想要的。

要在运行ReadTCP 的同时并行运行某些内容,请为任务创建一个变量,稍后再创建await

var readTask = ReadTCP();
DoOtherStuff();
AndMoreStuff();
AllAtOnce();
var response = await readTask;
DoSomethingWith(response);

顺便说一句,您不必将异步方法包装在 Task.Run 中。而不是做:Task.Run(() => FPXreaderTCP.ReadToEndAsync());,只做await FPXreaderTCP.ReadToEndAsync()

【讨论】:

我不需要在方法完成后将响应存储在任何地方。它用它做一些事情,比如写入数据库——这部分已经是多线程安全的。 @FilipS 仍然,让它返回Task(简单来说,异步等效于void)和await它在代码中的适当位置。

以上是关于在一种方法上同时使用等待/异步和线程是不是可行?的主要内容,如果未能解决你的问题,请参考以下文章

Dart 异步

Dart 异步

PHP 异步使用swoole的可行性测试

并发 并行 同步 异步 多线程的区别

异步操作

C#如何使用异步编程BeginInvoke/EndInvoke