重复使用并发运行的任务
本文关键字:运行 任务 并发 | 更新日期: 2023-09-27 17:58:33
好的,我已经改变了问题本身,因为我认为它不是很清楚。
public void Start()
{
IEnumerable<Action> originalTasks = new Action[] { () => LongRunningMethod(), () => LongRunningMethod2() };
Parallel.ForEach(originalTasks, task =>
{
task.Invoke();
});
}
public void LongRunningMethod()
{
Console.WriteLine("Long running method executed.");
Thread.Sleep(10000);
}
public void LongRunningMethod2()
{
Console.WriteLine("Long running method 2 executed.");
}
您将看到我有两个方法"LongRunningMethod()"answers"LongRunning Method2()"。"LongRunningMethod"的睡眠时间为10秒。
以下是我想要实现的目标。
应该输入并行foreach(事实就是这样),一旦我进入并行循环,5秒的计时器就会启动。当这5秒钟结束时,我想重新运行并行循环(我知道在这种情况下这不好,因为我正在启动一个线程,而另一个线程仍在运行。
在生产环境中,每个任务都有一个名为"isRunning"的变量,我将使用它来查看是否可以重新运行它。
我希望有人能在这个问题上给我一些帮助。
亲切问候,
也许您可以使用自定义状态对象来控制程序的流程。该状态对象将在延续方法中使用,以确定哪些任务已完成并应重新安排。
样品:
class TaskState
{
public int OneSecondTaskId { get; set; }
public int TenSecondTaskId { get; set; }
public bool ShouldRescheduleOneSecondTask { get; set; }
public bool ShouldRescheduleTenSecondsTask { get; set; }
}
class Program
{
static void Main(string[] args)
{
Task oneSecondTask = null;
Task tenSecondTask = null;
var state = new TaskState()
{
ShouldRescheduleOneSecondTask = true,
ShouldRescheduleTenSecondsTask = true
};
while (true)
{
if (state.ShouldRescheduleOneSecondTask)
{
oneSecondTask = Task.Factory.StartNew(
() =>
{
Thread.Sleep(1000);
Console.WriteLine("Slept 1 second");
});
state.OneSecondTaskId = oneSecondTask.Id;
state.ShouldRescheduleOneSecondTask = false;
}
if (state.ShouldRescheduleTenSecondsTask)
{
tenSecondTask = Task.Factory.StartNew(
() =>
{
Thread.Sleep(10000);
Console.WriteLine("Slept 10 seconds");
});
state.TenSecondTaskId = tenSecondTask.Id;
state.ShouldRescheduleTenSecondsTask = false;
}
var handleTaskCompletionTask = Task.WhenAny(oneSecondTask, tenSecondTask).ContinueWith(
(completedTask, o) =>
{
var taskState = (TaskState)o;
var taskId = completedTask.Result.Id;
if (taskId == taskState.OneSecondTaskId)
{
taskState.ShouldRescheduleOneSecondTask = true;
}
if (taskId == taskState.TenSecondTaskId)
{
taskState.ShouldRescheduleTenSecondsTask = true;
}
}, state);
handleTaskCompletionTask.Wait();
}
}
}
输出:
Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 10 seconds Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 1 second Slept 10 seconds Slept 1 second Slept 1 second ...
因此,首先,为了在每个任务结束后运行一些代码,并对该任务进行进一步处理,您需要对每个任务调用ContinueWith
。
要在它们全部启动5分钟后做某事,您可以使用Task.Delay
。
IEnumerable<Task> originalTasks = CreateTasks();
var continuations = originalTasks.Select(task =>
task.ContinueWith(t =>
{
DoStuffWithTask(t);
}))
.ToList();
Task.Delay(TimeSpan.FromMinutes(5))
.ContinueWith(t => CheckOnTasks());