Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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#_Task - Fatal编程技术网

如何在c#中运行多个任务,并在这些任务完成时获取事件?

如何在c#中运行多个任务,并在这些任务完成时获取事件?,c#,task,C#,Task,当任务完成时,我正在重新运行任务。下面是我在应用程序的应用程序\u Start中调用的函数 private void Run() { Task t = new Task(() => new XyzServices().ProcessXyz()); t.Start(); t.ContinueWith((x) => { Thread.Sleep(ConfigReader.CronReRunTimeInSeconds); Ru

当任务完成时,我正在重新运行任务。下面是我在应用程序的
应用程序\u Start
中调用的函数

private void Run()
{
    Task t = new Task(() => new XyzServices().ProcessXyz());
    t.Start();
    t.ContinueWith((x) =>
    {
        Thread.Sleep(ConfigReader.CronReRunTimeInSeconds);
        Run();
    });
}
我想运行多个任务,编号将从web.config应用程序设置中读取

我正在尝试这样的事情

private void Run()
{
    List<Task> tasks = new List<Task>();
    for (int i = 0; i < ConfigReader.ThreadCount - 1; i++)
    {
        tasks.Add(Task.Run(() => new XyzServices().ProcessXyz()));
    }

    Task.WhenAll(tasks);

    Run();
}
private void Run()
{
列表任务=新列表();
对于(int i=0;inewxyzservices().ProcessXyz());
}
任务。WhenAll(任务);
Run();
}

正确的方法是什么?

我相信您正在寻找:

Task.WaitAll(tasks.ToArray());

如果您想等待所有任务完成,然后重新启动它们,Marks的答案是正确的

但是,如果希望随时运行ThreadCount任务(在其中任何一个任务结束后立即启动新任务),则


如果要一个接一个地运行任务

await Task.Run(() => new XyzServices().ProcessXyz());
await Task.Delay(ConfigReader.CronReRunTimeInSeconds * 1000);
如果要在任务计划程序允许的情况下并发运行它们

await Task.WhenAll(new[]
    {
        Task.Run(() => new XyzServices().ProcessXyz()),
        Task.Run(() => new XyzServices().ProcessXyz())
    });

所以,你的方法应该是

private async Task Run()
{
    var tasks =
        Enumerable.Range(0, ConfigReader.ThreadCount)
        .Select(i => Task.Run(() => new XyzServices().ProcessXyz()));

    await Task.WhenAll(tasks); 
}

如果您不想深入构建自己的taskrunner/扩展该类,我可能会使用
tasks.first().wait()等待第一个任务结束
然后使用带有线程的while循环。休眠以观察剩余任务的状态。是否要在预定的时间间隔内重复运行一段代码?听起来像是计时器存在的确切原因,真的。当然,如果您想坚持这一点,只需将您的继续绑定到
任务的结果。whalll
和所有操作都将与以前一样。您需要
等待任务。whalll(任务)
Task.WaitAll(任务)。一个是异步调用,应该等待,另一个是可以在同步上下文中调用的普通函数。当然,您也可以使用丑陋的
任务.WhenAll(tasks.Wait()你错过了对
ToArray()
射击的调用!这正是我所需要的。@Amit此处使用的列表与示例中使用的数组之间存在差异,谢谢:)
WaitAll
是前
async
wait
方法,它不必要地绑定了主线程@Yasser,这将起作用,但您应该使用
任务。当所有
时,查找它。为什么要使用内部
任务。运行
?您正在占用一个线程阻塞,而另一个线程用于同步运行某些东西。只需使用
sem.Wait();试试{runwhatch();}最后{sem.Release();}
@Luaan不,这不是我想用代码做的。我不是在等待一项任务完成后再开始一项新任务。只要其中一个任务完成,我就创建一个新任务。因此,始终会有ThreadCount任务运行..而不是tasks.Whalll使用ThreadPool,该ThreadPool一次自动运行“最佳”数量的任务,同时对其他任务进行排队?在异步上下文中,我强烈希望在信号量上使用
WaitAsync()
。这里没有理由不切换到异步上下文。@RoyT。不确定,但在这种情况下会更有意义。是围绕并行运行任务而构建的,不需要将其与异步方法(如
任务)混合使用。除非您的工作是异步的,否则所有的
都是异步的。我在前面读到,等待任务并不是启动任务执行的原因,而是它们实际上是立即启动的。这是正确的吗?这会使您的第一个语句复杂化。如果您正在调用的函数本身是异步的,则不需要将它们包装在
任务中。运行
。但是,重要的是要实现异步任务将立即在当前线程上启动,并且只有在它运行到异步调用本身时才切换上下文。对于CPU密集型函数,您当然应该将它们包装到
任务中。运行
,对于快速切换到异步调用(通常是IO)的函数,不包装它们可以获得更好的性能。
private async Task Run()
{
    var tasks =
        Enumerable.Range(0, ConfigReader.ThreadCount)
        .Select(i => Task.Run(() => new XyzServices().ProcessXyz()));

    await Task.WhenAll(tasks); 
}