主线程和worker分离

Posted

技术标签:

【中文标题】主线程和worker分离【英文标题】:Main thread and workers separated 【发布时间】:2021-04-22 19:41:28 【问题描述】:

我觉得有点迷茫,找到一个好方法来获得一些关于如何解决我的线程问题 C# Unity 的想法。我试图实现的是从长时间运行的任务中卸载我的主线程。这是为了避免主线程等待一个或多个任务完成,然后主线程才能像往常一样继续。

现在我有这个测试代码。

    public void Start()
    
        var workers = new List<DataChunk>();

        workers.Add(new DataChunk());
        workers.Add(new DataChunk());
        foreach (var worker in workers)
        
            Task.Run(() => worker);
        
    

DataChunck 只是在此测试中进行了条带化​​,它可以包含所有假定作为完整任务包含的过程。所以现在我这里只有一个计时器来模拟正在做的事情并花时间。

    public class DataChunk
    
        public bool isDone = false;
        public DataChunk()
                   
           System.Random r = new System.Random();
           int rInt = r.Next(1000, 2000); 
           Thread.Sleep(rInt);
           allDataLoaded = true;
           Debug.Log("Done " + rInt);
           isDone = true;
        
    

这并没有真正做到我最终想要实现的目标,因为它只执行这些作为连续任务执行的 DataChunk,从不放开主线程。

我认为缺少的是制作这个 asyc,因此它们可以从主线程启动,然后最好不必等待主线程完成。因为这应该尽可能从队列中检查。

如果我愿意将其可视化,则应该像这样工作。

有谁愿意分享实现这种基于线程或基于任务的行为所缺少的东西吗?

【问题讨论】:

请注意,在 Unity 中,处理事情的方式可能与其他基于 dotnet 的应用程序类型完全不同,我只有后者的经验。所以请记住这一点。如果你想产生一个 CPU 密集型任务,你通常会await 一个任务,它是由 Task.Run 启动的。如果您想一次启动几个任务并等到全部完成,您将启动它们,保留任务并通过await Task.WhenAll(tasks) 等待它们……但正如我所说,在 Unity 中,可能还有其他方法. 我刚刚在阅读,我记忆中的内容是“协程”,但现在它们似乎已经过时了。不过,您可能想做一些研究。我真的不知道 Unity 中是否有一些关于异步任务的“特殊怪癖”。 顺便说一句:您的示例 DataChunk 正在 CTOR 中睡觉。因此,“模拟工作”在您创建块的行中完成,而不是在任务执行时完成。 【参考方案1】:

您在 DataChunk 构造函数中调用 Thread.Sleep:workers.Add(new DataChunk()),因此您的 Thread.Sleep 步骤不是并行执行的。

最好将 Thread.Sleep 逻辑移到 DataChunk 构造函数之外的某个 DataChunk 类方法中,并从 Task.Run(() => worker.SomeMethodWithThreadSleep()) 中调用此方法;

【讨论】:

Dimitry 是对的。您对Sleep 的所有调用当前都在循环之前完成,因此在Task.Run() 之外。表达式() =&gt; worker 是一个只返回worker 的函数,所以它实际上什么都不做。

以上是关于主线程和worker分离的主要内容,如果未能解决你的问题,请参考以下文章

Web Worker的使用

Web Worker 是在主 ui android 线程还是单独的线程上运行?

OpenHarmony stage worker 多线程

web worker && webSocket

HTML5(四)——Web Workers

Memcached源码分析之线程模型