【发布时间】:2020-04-16 21:36:00
【问题描述】:
我正在使用任务和等待/异步进行编程。我假设多线程的工作方式与 NodeJS 或 Python 中的一样,也就是说,它没有,一切都在同一个线程上运行。但我一直在尝试了解任务实际上是如何执行的,我的理解是它们是由 TaskScheduler 执行的。默认谁的实现是隐藏的,但可以预期使用 ThreadPool。
我是否应该像我的所有任务都可以在任何线程中运行一样进行编程?
我的异步编程范围是相当轻量级的 CPU 工作,由几个无限循环组成,这些无限循环确实有效,然后在 Task.Delay 上等待几秒钟。现在唯一的共享资源是一个 int,每次我写网络消息时都会递增,但我希望将来我的任务将是共享字典和列表。
我还有一个网络任务,它连接到 TCP 服务器并使用我在 BeginRead+EndRead 上实现的任务读取消息。 Read 函数由一个无限循环调用,该循环读取一条消息,对其进行处理,然后读取一条新消息。
void OnRead(IAsyncResult result)
{
var pair = (Tuple<TaskCompletionSource<int>, NetworkStream>)result.AsyncState;
int count = pair.Item2.EndRead(result);
pair.Item1.SetResult(count);
}
async Task<byte[]> Read(NetworkStream stream, uint size)
{
var result = new byte[size];
var count = 0;
while(count < size)
{
var tcs = new TaskCompletionSource<int>();
stream.BeginRead(result, count, result.Length - (int)count, new AsyncCallback(OnRead), Tuple.Create(tcs, stream));
count += await tcs.Task;
}
return result;
}
我使用同步写入写入 NetworkStream。
【问题讨论】:
-
你能更具体地说明你想做什么吗?有很多方法可以解决问题,但这很大程度上取决于您拥有的应用程序。一个简短的回答就是你的问题是,是的。
-
有两种类型的任务。在后台线程中卸载 CPU 密集型工作的任务,以及促进异步性的承诺式任务。
TaskScheduler仅与第一种类型相关。您打算自己执行什么样的任务? -
@TolgaEvcimen,我添加了更多细节。
-
@TheodorZoulias,后者。一项任务是网络绑定的,所有其他任务都使用循环中的 Task.Delay 来定期完成工作。
-
为什么要使用BeginRead/EndRead和TaskCancellationSource,而不是直接使用ReadAsync?这将大大简化您的代码,因为您不再需要 OnRead 回调,也不需要声明和访问 TaskCancellationSource。
标签: c# .net multithreading async-await