在一种方法上同时使用等待/异步和线程是不是可行?
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
,使其返回Task
(async 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
它在代码中的适当位置。以上是关于在一种方法上同时使用等待/异步和线程是不是可行?的主要内容,如果未能解决你的问题,请参考以下文章