C# WFA - 将耗时的工作委托给另一个线程
Posted
技术标签:
【中文标题】C# WFA - 将耗时的工作委托给另一个线程【英文标题】:C# WFA - delegate time consuming work to another thread 【发布时间】:2019-01-08 23:02:01 【问题描述】:我想在 C# (WFA) 中创建一些机制,允许我在运行中向一个特定的单独线程添加一些函数。
public class MyClass
private Thread specialThread = new Thread();
MyClass()
regularMethod();
specialThread.AddNextJob( veryLongTimeConsumingMethod() );
//....
anotherUseMethod();
private void veryLongTimeConsumingMethod()
//...time consuming database, logic, etc...
this.UIThread(delegate ()
control1.Items = updatedItems;
);
private void anotherUseMethod()
//...another method wants to do a long job
specialThread.AddNextJob(veryLongTimeConsumingMethod());
在所有“工作”完成后,我希望“特殊线程”处于“待机”状态(等待另一个“工作”)。我需要按顺序完成所有“工作”。 有什么通用的方法可以实现吗?
【问题讨论】:
【参考方案1】:我不久前写过这样的东西。现在你可能会使用 async await 来让东西在后台线程上运行。但这是我写的一个快速任务队列。
public class TaskQueue
public Queue<Task> CurrentTasks get; private set;
public bool TaskQueueRunning get; private set;
public TaskQueue()
CurrentTasks = new Queue<Task>();
TaskQueueRunning = false;
public void AddTask(Task task)
CurrentTasks.Enqueue(task);
ProcessTasks();
private void ProcessTasks()
if (!TaskQueueRunning)
TaskQueueRunning = true;
ProcessIndividualTask();
private void ProcessIndividualTask()
if (CurrentTasks.Count > 0)
TaskItem currenttask = CurrentTasks.Dequeue();
currenttask.CurrentTask.ContinueWith(x => ProcessIndividualTask());
currenttask.CurrentTask.Start();
else
TaskQueueRunning = false;
你在你的主窗体上实例化它:
private TaskQueue backgroundtasks = new TaskQueue();
然后,当您想在后台线程上执行方法时,您将其包装在任务中。例如
Task newtask = new Task(() => MyMethodCall());
backgroundtasks.AddTask(newtask);
或者如果你想内联整个东西:
backgroundtasks.AddTask(new Task(() => MyMethodCall()));
如果任务队列中没有项目,则队列不会运行,如果添加项目,队列将运行。如果您在第一个任务完成时添加多个项目,它将ContinueWith
下一个任务。任务将始终按顺序运行,因为底层类型是队列,只有在当前任务完成后才会运行下一个任务。
这样做的一个限制是您的任务无法返回结果。不过,您可以设置一个任务来写入变量。例如
Task newtask = new Task(() =>
myvar = MyMethodCall();
);
backgroundtasks.AddTask(newtask);
这假设您的主窗体上有一个名为 myvar 的属性/变量。但是要小心这一点,因为如果您从不同的任务多次写入同一个变量,您将无法预测任何时候该值是什么 - 特别是如果您从不同的线程访问它。说到跨线程——这里没有防护,所以要特别小心。
建议您研究 Async 和 Await,因为您可能会发现它们更适合您想做的事情。
【讨论】:
投反对票的人愿意评论为什么这个答案被投反对票吗?以上是关于C# WFA - 将耗时的工作委托给另一个线程的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中按下停止按钮来停止耗时过长的 UI 线程 [关闭]
C# 耗时的程序 界面卡死,如何做一个缓冲界面,例如有个圆圈在旋转的效果展示