c# - 如何在 .NET 4.5 中运行这两种方法 'at the same time'?

标签 c# .net task async-await multitasking

我有一个方法可以执行 2 个独立 逻辑 block 。我希望我可以同时运行它们 ..只有在这两个子方法都完成后才能继续。

我试图了解 async/await 语法,但我就是不明白。

代码如下:

public PewPew SomeMethod(Foo foo)
{
    var cats = GetAllTheCats(foo);
    var food = GetAllTheFood(foo);

    return new PewPew
               {
                   Cats = cats,
                   Food = food
               };
}

private IList<Cat> GetAllTheCats(Foo foo)
{
    // Do stuff, like hit the Db, spin around, dance, jump, etc...
    // It all takes some time.
    return cats;
}

private IList<Food> GetAllTheFood(Foo foo)
{
    // Do more stuff, like hit the Db, nom nom noms...
    // It all takes some time.
    return food;
}

所以对于上面的代码,我想说:去同时获取所有的猫和食物。完成后,返回一个新的 PewPew

我很困惑,因为我不确定上面的哪些类是 async 或返回 Task 等。所有这些?只有两个私有(private)的?我还猜测我需要利用 Task.WaitAll(tasks) 方法,但我不确定如何设置任务同时运行。

有什么建议吗,好心人?

最佳答案

以下是您可能想要执行的操作:

public async Task<PewPew> SomeMethod(Foo foo)
{
    // get the stuff on another thread 
    var cTask = Task.Run(() => GetAllTheCats(foo));
    var fTask = Task.Run(() => GetAllTheFood(foo));

    var cats = await cTask;
    var food = await fTask;

    return new PewPew
               {
                   Cats = cats,
                   Food = food
               };
}

public IList<Cat> GetAllTheCats(Foo foo)
{
    // Do stuff, like hit the Db, spin around, dance, jump, etc...
    // It all takes some time.
    return cats;
}

public IList<Food> GetAllTheFood(Foo foo)
{
    // Do more stuff, like hit the Db, nom nom noms...
    // It all takes some time.
    return food;
}

这里有两点你需要明白:

1) 这之间有什么区别:

var cats = await cTask;
var food = await fTask;

还有这个:

Task.WaitAll(new [] {cTask, fTask});

在让 2 个 async 任务完成然后 返回新的 PewPew 的意义上,两者都会给你类似的结果 - 然而,区别在于 Task.WaitAll( ) 将阻塞当前线程(如果是 UI 线程,则 UI 将卡住)。相反,await 将分解状态机中的 SomeMethod 语句,并在遇到 await 时从 SomeMethod 返回给它的调用者 关键字。它不会阻塞线程。 await 下面的代码将安排在 async 任务结束时运行。

2) 你也可以这样做:

var cats = await Task.Run(() => GetAllTheCats(foo));
var food = await Task.Run(() => GetAllTheFood(foo));

但是,这不会同时启动 async 任务。第二个任务将在第一个任务结束后开始。这是因为 await 关键字的工作原理,希望对您有所帮助...

编辑:如何使用 SomeMethod - 在调用树开始的某处,您必须使用 Wait()Result 属性- 或者 - 您必须从 async voidawait。 通常,async void 将是一个事件处理程序:

public async void OnSomeEvent(object sender, EventArgs ez) 
{ 
  Foo f = GetFoo();
  PewPew p = await SomeMethod(f);
}

如果不是,则使用 Result 属性。

public Foo2 NonAsyncNonVoidMethod() 
{
   Foo f = GetFoo();
   PewPew p = SomeMethod(f).Result; //But be aware that Result will block thread

   return GetFoo2(p);
}

关于c# - 如何在 .NET 4.5 中运行这两种方法 'at the same time'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16728338/

相关文章:

c# - 复制 C# 多维数组元素的最有效方法是什么?

c# - 如何使用 AutoFixture 为属于类的属性生成数据?

c# - WPF Dispatchertimer 延迟 react /卡住

c# - 如何使用 .NET 高效地为 FAST ESP 提供千兆字节的数据

java - Spring 任务异步和延迟

c# - PostMessage 和 SendMessage WM_SETCURSOR、WM_LBBUTTONDOWN/UP 等都发送 xPox0、yPos0

c# - 全选显示完成和未完成的记录

.net - 如何从 PDB 文件中删除构建路径

c# - 同步实现异步方法

C# 等待集合