我想在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());
}
}
在所有“工作”完成后,我希望“ specialThread”处于“待命”状态(等待另一个“工作”)。我需要做所有的“工作”,以便添加它们。 有什么通用的方法可以做到这一点吗?
答案 0 :(得分:-1)
我前一段时间写了这样的东西。如今,您可能会使用async等待来使内容在后台线程上运行。但是,这是我编写的快速TaskQueue。
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的主窗体上具有属性/变量。但是要特别小心,因为如果您从不同的任务多次写入相同的变量,则您将无法预测任何时间的值,尤其是当您从不同的线程访问它时。谈论跨线程-这里没有防护,所以要特别小心。
建议您研究“异步”和“等待”,因为它们可能更适合您的工作。