C# 重复使用并发运行的任务
好的,我改变了问题本身,因为我认为它不是很清楚C# 重复使用并发运行的任务,c#,parallel-processing,C#,Parallel Processing,好的,我改变了问题本身,因为我认为它不是很清楚 public void Start() { IEnumerable<Action> originalTasks = new Action[] { () => LongRunningMethod(), () => LongRunningMethod2() }; Parallel.ForEach(originalTasks, task => { task.Invoke();
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.");
}
public void Start()
{
IEnumerable originalTasks=新操作[]{()=>LongRunningMethod(),()=>LongRunningMethod2()};
Parallel.ForEach(originalTasks,task=>
{
task.Invoke();
});
}
公共void LongRunningMethod()
{
WriteLine(“执行了长时间运行的方法”);
睡眠(10000);
}
公共无效LongRunningMethod2()
{
WriteLine(“执行了长时间运行的方法2”);
}
您将看到我有两个方法“LongRunningMethod()”和“LongRunningMethod2()”。
“LongRunningMethod”的睡眠时间为10秒
下面是我想要实现的目标
应该输入并行foreach(这种情况下),一旦我进入并行循环,一个5秒的计时器就会启动。当这5秒钟结束时,我想重新运行并行循环(我知道在这种情况下这不好,因为我正在启动一个线程,而另一个线程仍在运行)
在生产环境中,每个任务都有一个名为“isRunning”的变量,我将使用该变量查看是否可以重新运行它
我希望有人能在这个问题上给我一些帮助
好心的问候,首先,在每个任务结束后运行一些代码,并对您要调用的任务执行一些进一步的处理,然后对每个任务执行
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());
IEnumerable originalTasks=CreateTasks();
var continuations=originalTasks.Select(任务=>
task.ContinueWith(t=>
{
dostufwithtask(t);
}))
.ToList();
任务延迟(时间跨度从分钟(5))
.ContinueWith(t=>CheckOnTasks());
也许您可以使用自定义状态对象控制程序的流程。此状态对象将用于continuation方法中,以确定哪些任务已完成,哪些任务应重新安排
样本:
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();
}
}
}
输出:
你的问题是什么?:)不能保证
并行。ForEach
并行运行。我知道,但至少一项耗时5小时的任务不会阻塞所有其他内容。你看过任务。WaitAll()
?如果是,为什么不使用它呢?好的,我想你真正想要的是Task.whenny()
。此方法会一直阻塞,直到许多任务中的一个任务完成,并将完成的任务传递给continuation方法。此延续是您处理重新安排已完成任务的地方。谢谢,这开始有意义了,但在您的示例中,您使用“ContinueWith”并指定了特定任务。但是我的任务不同,那么我应该在ContinueWith方法中放置哪个任务,而不是哪个任务?如果问题是并非所有任务都像我的示例中那样返回void
,那么您可以使用.ContinueWith()
重载显式指定返回类型。抱歉,我不明白。你能看看我的帖子吗。我把它改成了现在的代码。如果你能修改我的代码使其功能齐全,那就太好了,因为我真的迷失在森林里了。提前谢谢。我看了你最新的问题。在您可以等待任务完成时轮询任务的状态是一种奇怪的做法。你确定要使用计时器吗?我使用并行。为了每一个时刻。你在哪里看到我的计时器?
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
...