Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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#_Visual Studio_Windows Runtime_Win Universal App_Windows 10 - Fatal编程技术网

C# 从连续异步方法中获取任务(非并行)

C# 从连续异步方法中获取任务(非并行),c#,visual-studio,windows-runtime,win-universal-app,windows-10,C#,Visual Studio,Windows Runtime,Win Universal App,Windows 10,关于如何在特定情况下使用wait/async模式,我还有另一个问题 假设我在一个方法中,这个方法在一个项目集合上循环,我想并行执行一些东西。因此,我创建了一个列表,对于循环的每次迭代,我在后台开始一些工作,并将其任务添加到该列表中。在方法的末尾,我将调用Task.whalll 现在,假设在我的循环中,有两个异步方法不能并行执行,也就是说,第一个方法完成后,需要调用第二个方法 如果不进行优化,代码将如下所示: // Lets assume I have an items list inside e

关于如何在特定情况下使用wait/async模式,我还有另一个问题

假设我在一个方法中,这个方法在一个项目集合上循环,我想并行执行一些东西。因此,我创建了一个
列表
,对于循环的每次迭代,我在后台开始一些工作,并将其
任务
添加到该列表中。在方法的末尾,我将调用Task.whalll

现在,假设在我的循环中,有两个异步方法不能并行执行,也就是说,第一个方法完成后,需要调用第二个方法

如果不进行优化,代码将如下所示:

// Lets assume I have an items list inside each loop iteration
await FirstMethodAsync(items);
await items.SecondMethodAsync(item => item.SomeProperty);
现在,由于循环可以在调用这两个方法时继续进行,因此这种方法实际上效率很低。 注意:我希望main方法在这两个链式异步方法在后台运行时保持运行

第二种方法:我已准备好我的
列表
,并在循环的每次迭代中添加一个新任务。问题是,第二个方法必须在第一个方法之后调用。这是我目前的解决方案:

// Let's assume my List<Task> is simply called tasks
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
FirstMethodAsync(items).ContinueWith(t1 => items.SecondMethodAsync(item => item.SomeProperty).ContinueWith(t2 => tcs.SetResult(null)));
tasks.Add(tcs.Result);

// Later on, at the end of the loop and right before the method returns
await Task.WhenAll(tasks);
//假设我的列表就是任务
TaskCompletionSource tcs=新的TaskCompletionSource();
FirstMethodAsync(items).ContinueWith(t1=>items.SecondMethodAsync(item=>item.SomeProperty).ContinueWith(t2=>tcs.SetResult(null));
tasks.Add(tcs.Result);
//稍后,在循环结束时和方法返回之前
等待任务。何时(任务);
这是可行的,只要我调用第一个线程,控件就会返回循环迭代,这就是我想要实现的。因此,我去掉了两个
await
操作符,整个解决方案似乎很好

我只是不确定这是不是最好的方法:必须创建一个
TaskCompletionSource
并使用
方法调用这两个嵌套的
ContinueWith,这会使代码看起来很糟糕,而且肯定有更好的方法来实现这一点。

最好的方法(例如,最干净、最可能是正确的、最容易维护)解决方案是使用单独的方法:

  for (...)
  {
    tasks.Add(BothMethodsAsync(items));
  }
  await Task.WhenAll(tasks);


async Task BothMethodsAsync(... items)
{
  await FirstMethodAsync(items);
  await items.SecondMethodAsync(item => item.SomeProperty);
}
最好(如中所述,最干净、最可能正确且最容易维护)的解决方案是使用单独的方法:

  for (...)
  {
    tasks.Add(BothMethodsAsync(items));
  }
  await Task.WhenAll(tasks);


async Task BothMethodsAsync(... items)
{
  await FirstMethodAsync(items);
  await items.SecondMethodAsync(item => item.SomeProperty);
}

对不起,我不明白等待方法有什么问题?什么使它“低效”?我的意思是,使用
await
操作符会阻塞该方法,直到这两个等待的调用完成,而我希望在后台线程中与这两个链接的方法并行执行主方法的其余部分,以优化性能。因此,为什么不单独创建一个包含这两个
await
操作符的方法呢?是的,这会起作用,我可以将整个方法的任务添加到列表中,但我正在寻找一种优雅/干净的方法,在主方法的主体中实现这一点,并且不需要额外的异步方法来调用。分解成一个单独的方法肯定是最好的方法,正如我在博客上所描述的。对不起,我不明白
wait
方法有什么问题?什么使它“低效”?我的意思是,使用
await
操作符会阻塞该方法,直到这两个等待的调用完成,而我希望在后台线程中与这两个链接的方法并行执行主方法的其余部分,以优化性能。因此,为什么不单独创建一个包含这两个
await
操作符的方法呢?是的,这会起作用,我可以将整个方法的任务添加到列表中,但我正在寻找一种优雅/干净的方法,在主方法的主体中实现这一点,并且不需要额外的异步方法来调用。分解成一个单独的方法肯定是最好的方法,正如我在博客上描述的那样。