gpt4 book ai didi

c# - 多线程代码中频繁出现滞后峰值

转载 作者:行者123 更新时间:2023-11-30 16:30:53 25 4
gpt4 key购买 nike

我正在尝试使我的简单 C# 图形库成为多线程的。但是引入这段代码后:

/* foreach (IAffector affector in affectorLookup.Values)
affector.Update(timestep); */

taskManager.Value = timestep; taskManager.Start();

foreach (IAffector affector in affectorLookup.Values)
taskManager.AddToQueue(affector.Update);
taskManager.StopWhenDone();
taskManager.Wait();

模拟开始出现尖锐的滞后峰值,这似乎起源于 TaskHandler.Run(我不能确定,因为添加之前的代码会使我的代码分析器忽略 TaskHandler.Run 之外的任何内容)。

任务管理器:

public class TaskManager
{
public delegate void MethodDel(float timestep);
private Queue<MethodDel> queue;
private List<TaskHandler> handlers;
private float value;


public float Value
{
get
{
return value;
}
set
{
this.value = value;
}
}


public TaskManager()
{
this.queue = new Queue<MethodDel>();
this.handlers = new List<TaskHandler>(System.Environment.ProcessorCount);

for (int t = 0; t < this.handlers.Capacity; ++t)
this.handlers.Add(new TaskHandler(this));

this.value = 0;
}


public void Start()
{
foreach (var handler in handlers)
handler.Start();
}


public void Stop()
{
lock (queue)
queue.Clear();

foreach (var handler in handlers)
handler.StopWhenDone();
}


public void StopWhenDone()
{
foreach (var handler in handlers)
handler.StopWhenDone();
}


public void AddToQueue(MethodDel method)
{
lock (queue)
queue.Enqueue(method);
}


public bool GetFromQueue(out MethodDel method)
{
lock (queue)
{
if (queue.Count == 0) { method = null; return false; }

method = queue.Dequeue();
return true;
}
}


public int GetQueueCount()
{
return queue.Count;
}

internal void Wait()
{
// Have to wait for them one at a time because the main thread is STA.

WaitHandle[] waitHandles = new WaitHandle[1];
// for (int t = 0; t < handlers.Count; ++t)
// waitHandles[t] = handlers[t].WaitHandle;

// WaitHandle.WaitAll(waitHandles);
for (int t = 0; t < handlers.Count; ++t)
{ waitHandles[0] = handlers[t].WaitHandle; WaitHandle.WaitAll(waitHandles); }
}
}

任务处理程序:

public class TaskHandler
{
private TaskManager manager;
private Thread thread;
private bool stopWhenDone;
private ManualResetEvent waitHandle;


public ManualResetEvent WaitHandle
{
get
{
return waitHandle;
}
}


public TaskHandler(TaskManager manager)
{
this.manager = manager;
}


public void Start()
{
waitHandle = new ManualResetEvent(false);

stopWhenDone = false;

thread = new Thread(Run);
thread.IsBackground = true;
thread.SetApartmentState(ApartmentState.MTA);
thread.Start();
}


public void StopWhenDone()
{
this.stopWhenDone = true;
}

// Possible source of slowdown
private void Run()
{
TaskManager.MethodDel curMethod;
while (!stopWhenDone || manager.GetQueueCount() > 0)
{
if (manager.GetFromQueue(out curMethod))
{
curMethod(manager.Value);
}
}
waitHandle.Set();
}
}

最佳答案

启动线程是一项繁重的操作。不确定它是否像您遇到的那样沉重,但可能就是这样。此外,让所有处理并行运行可能会给您的系统带来很大的压力,而可能带来的好处很少......

关于c# - 多线程代码中频繁出现滞后峰值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5274494/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com