如何异步并行延迟运行多个方法

3
我试图同时运行两个方法。第一个方法连接到ftp服务器并下载一些数据。由于我想要减少网络流量,它应该每30秒运行一次。与此同时,我希望另一个方法每10秒独立于第一个方法运行。
问题在于我无法让这两个方法同时运行或有序延迟。
namespace Example
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await Task.Run(async () =>
            {
                while (true)
                {
                    await Every10s();
                    await Every30s();
                }
            });
        }

        public static async Task<bool> Every10s()
        {
            await Task.Delay(10000);
            Console.Writeline("10s");
            return true;
        }

        public static async Task<bool> Every30s()
        {
            await Task.Delay(30000);            
            Console.Writeline("30s");
            return true;
        }
    }
}

我期望输出以下内容,并在它们之间加上相应的暂停时间: 10秒 10秒 10秒 30秒 10秒 10秒 10秒 30秒 ...
但是实际上这两种方法都会等待对方,所以我得到的输出是 10秒 30秒 10秒 30秒 10秒 30秒,其中有40秒的暂停。
欢迎提供任何帮助和提示。

2
不要等待方法返回任务,而应将它们存储在列表中,并对其执行await Task.WhenAll(list)。您需要在每个while循环中执行此操作。请注意,对于此用例,我建议使用计时器而不是async/await,因为这实际上就是计时器的定义。另一个不在此处使用async/await的原因是因为async/await并不真正并行(我会在这里链接到一篇很棒的文章,但我忘记了它来自哪里)。 - Joelius
你把并行执行和异步执行混淆了。异步不等同于并行。 - iSpain17
@iSpain17非常正确,忘了提到这一点。我会添加的。 - Joelius
2
这个程序会怎样结束?没有办法退出无限循环! - Theodor Zoulias
我忘记了这篇文章的来源,但是有很多类似的资源,比如这个答案这个问题等等,只要稍微搜索一下就可以找到更多。 - Joelius
@Joelius,谢谢你指出这一点,我也会尝试使用计时器。 - Pietr Podschinski
1个回答

4
因为我想减少网络流量,所以它应该每30秒运行一次。同时,我希望另一个方法每10秒独立于第一个方法运行。
你有两个独立的工作循环,所以你需要在你的代码中有两个循环:
async Task RunEvery10s()
{
  while (true)
    await Every10s();
}

async Task RunEvery30s()
{
  while (true)
    await Every30s();
}

await Task.WhenAll(RunEvery10s(), RunEvery30s());

1
这个程序会在什么时候以及如何终止? - Joelius
1
它将在所有前台线程退出时退出,就像任何其他程序一样。 - Stephen Cleary
我指的是任何类型的异常。如果没有引发异常,这些循环不会阻止进程退出。我同意添加取消功能是一个好主意,但由于它不在原始代码中,我也没有在这里添加它。 - Stephen Cleary
1
谢谢!我之前尝试过,但没有使用await methodname();也可以正常工作。我已经实现了取消异常;这段代码只是一个简化的例子。 - Pietr Podschinski
如果其中任何一个操作失败,它们的异常将从await Task.WhenAll抛出。我认为单个操作的失败不会通过await Task.WhenAll传播。两个操作必须以某种方式都完成,才能使await Task.WhenAll完成。 - Theodor Zoulias
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接