任务在另一个线程 .NET 上异步运行

Posted

技术标签:

【中文标题】任务在另一个线程 .NET 上异步运行【英文标题】:Task running asynchronously on another thread .NET 【发布时间】:2020-10-15 16:13:00 【问题描述】:

我有一个需要在另一个线程上异步执行的过程。该程序将批量处理多个数据(可以接收 2 个项目或 40000 个)。从本地测试来看,最长的运行时间约为 2 分钟(40000 个项目)。

场景如下: UI 调用后端,后端启动一个异步线程,该线程将运行该过程,然后返回一个布尔值,以了解是否收到请求(这些是要求,我不要使用等待/等待)。我不太确定在这之间使用什么:

Task.Run(()=> MyProcedure())

Task.Factory.StartNew(()=> MyProcedure(), TaskCreationOptions.LongRunning)

对于这种情况,最好的选择是什么?

【问题讨论】:

这两者没有区别。一个是另一个具有一些默认参数的别名。仅当您每秒调用其中一个时,它们的行为才会有所不同,例如,Task.Factory.StartNew 将创建大量线程,这实际上会减慢程序的速度。 【参考方案1】:

程序会批量处理一些数据

这可能意味着多种情况。如果你打算在这些批次中使用async/await,这样你的MyProcedure实际上是异步的,那么你应该可以使用Task.RunMyProcedure 在异步时将自身释放回线程池这一事实意味着这应该可以正常工作,例如:

异步任务 MyProcedure()

    而 (ThereIsWorkToDo)
    
       var batch = // ... 收集一些工作
       等待 ProcessBatchAsync(batch).ConfigureAwait(false);
    

但是:如果MyProcedure() 异步的,但您只想在后台运行它,那么是的,TaskCreationOptions.LongRunning 可能是合理的,但需要 2 分钟的时间:所以可能是一个常规的专用线程。

【讨论】:

MyProcedure() 不是异步的,我只是希望它在后台运行而不阻塞我的 UI 线程。并非总是需要 2 分钟,这取决于客户端选择的数据量。这就是我不太确定的原因,因为该操作大部分时间可以运行不到 1 秒,但在某些情况下可能需要长达 2 分钟(这是一个近似值)。 @user2399378 我可能会使用LongRunning 来避免在坏情况下出现问题;如果某件事说它是长时间运行的,但很快就结束了,这不是问题;但是,我也可能会认真考虑将方法更改为 真正异步。您说它通常在不到一秒的时间内运行的事实意味着“专用线程”方法不是一个好主意。 我不太确定会发生什么行为以及每个请求将选择多少个项目,我所知道的最大值是 50000 左右。您将方法更改为真正是什么意思异步?我只需要它在单独的线程上运行,以便让 UI 正常运行,它里面的代码可以同步运行。 @user2399378 如果它有效,那么最好停止戳它,并坚持你所拥有的

以上是关于任务在另一个线程 .NET 上异步运行的主要内容,如果未能解决你的问题,请参考以下文章

将异步任务发送到在其他线程中运行的循环

ConfigureAwait(false) 不会使延续代码在另一个线程中运行

在C#的同一个异步线程中运行不同的任务[重复]

长时间运行的任务,我应该在另一个线程或另一个进程中运行它们吗? [复制]

js的异步运行机制

异步操作