C# 需要统一的多线程策略

C# 需要统一的多线程策略,c#,multithreading,unity3d,C#,Multithreading,Unity3d,我的unity项目是Android上的一个程序化环境,在运行时创建地形和东西。我使用的整个工作流是计算工作线程中的任何非unity,当计算数据时,我在主线程中调用unity API 问题是工作线程有时会影响主线程的性能。这可能会在渲染时间上出现一个令人讨厌的峰值 那么在unity中如何处理多线程呢 编辑:android设备是四核的 编辑2:我相信山姆在评论中所说的正是发生的事情 我想知道您是否可以确定代码运行在哪个内核上,或者 您可以设置线程关联吗?我发现了一些链接 描述了类似情况:和。听起来像

我的unity项目是Android上的一个程序化环境,在运行时创建地形和东西。我使用的整个工作流是计算工作线程中的任何非unity,当计算数据时,我在主线程中调用unity API

问题是工作线程有时会影响主线程的性能。这可能会在渲染时间上出现一个令人讨厌的峰值

那么在unity中如何处理多线程呢

编辑:android设备是四核的

编辑2:我相信山姆在评论中所说的正是发生的事情

我想知道您是否可以确定代码运行在哪个内核上,或者 您可以设置线程关联吗?我发现了一些链接 描述了类似情况:和。听起来像 它偶尔会选择与主线程相同的内核

因此,这可能不是关于unity,而是关于每个实时交互式多线程应用程序。我相信可以在某些平台的某些版本上设置线程关联,但这会破坏系统的跨平台状态

PS:不完全是主要问题,但为了使问题更具体,我将包括工作线程实现。它是中建议的工作线程实现的修改版本。修改后的版本如下:

public static class JobScheduler
{
private static Queue<Job> Jobs = new Queue<Job>();
private static volatile bool isBusy;
private static ManualResetEvent _workAvailable = new ManualResetEvent(false);
static JobScheduler()
{
    var backgroundWorkThread = new Thread(BackgroundThread)
    {
        IsBackground = true,
        Priority = ThreadPriority.Lowest,
        Name = "BasicBackgroundWorker Thread"
    };
    backgroundWorkThread.Start();
}

private static void BackgroundThread()
{
    int jobCnt;
    while (true)
    {
        Job? workItem=null;
        lock (Jobs)
        {
            jobCnt = Jobs.Count;
            if (jobCnt != 0 && !isBusy)
            {
                workItem = Jobs.Dequeue();
            }
        }
        if (workItem!=null)
        {
            isBusy = true;
            workItem.Value.callback(workItem.Value.param);
        }
        else
        {
            _workAvailable.WaitOne();
            _workAvailable.Reset();
        }
    }
}
public static void AddJob(Job Job)
{
    lock (Jobs)
    {
            Jobs.Enqueue(Job);
    }
        _workAvailable.Set();
}

public static void JobDone()
{
    isBusy = false;
    _workAvailable.Set();
}

}
无论何时需要,我都会调用
JobScheduler.AddJob
将作业排队,并在作业完成后调用
JobScheduler.JobDone
,以允许下一个作业运行


另外,线程池不是一个选项,因为它会产生不必要的垃圾,使用起来也不是很灵活。

那么为什么它会影响主线程呢?主线程是否发送一个作业,然后等待该作业完成?主线程不应该等待后台线程,否则会破坏后台线程的功能。不,主线程不会等待任何工作完成。主线程调用JobScheduler.AddJob来取消某个作业,并在不中断的情况下继续其作业。作业将在后台线程中处理,完成后将其数据放入另一个队列。主线程在每一帧将一些处理过的数据排出来并使用它们。因此,基本上后台工作线程对主线程是完全透明的。当主线程退出队列时,如果队列是空的呢?它会一直等到队列中有东西出现吗?不会。如果有,它会把处理过的数据排出来。我怀疑这是操作系统线程时间限制的问题,当工作线程与主线程在同一个cpu上运行时,会出现峰值。但这只是一种预感,我无法证明任何事情,因为它是在安卓上的。愚蠢的问题-你的安卓设备有多个CPU内核吗?为什么它会影响主线程?主线程是否发送一个作业,然后等待该作业完成?主线程不应该等待后台线程,否则会破坏后台线程的功能。不,主线程不会等待任何工作完成。主线程调用JobScheduler.AddJob来取消某个作业,并在不中断的情况下继续其作业。作业将在后台线程中处理,完成后将其数据放入另一个队列。主线程在每一帧将一些处理过的数据排出来并使用它们。因此,基本上后台工作线程对主线程是完全透明的。当主线程退出队列时,如果队列是空的呢?它会一直等到队列中有东西出现吗?不会。如果有,它会把处理过的数据排出来。我怀疑这是操作系统线程时间限制的问题,当工作线程与主线程在同一个cpu上运行时,会出现峰值。但这只是一种预感,我无法证明任何事情,因为它是安卓系统。愚蠢的问题-你的安卓设备有多个CPU核心吗?
public struct Job
{
public object param;
public WaitCallback callback;
public Job(WaitCallback callBackP
    , object parameter)
{
    callback = callBackP;
    param = parameter;
}
}