Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重复使用并发运行的任务_C#_Parallel Processing - Fatal编程技术网

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
...