c# - 如何将任务结果传递给不使用延续的其他任务

标签 c# asynchronous async-await task-parallel-library task

我在 Func<Task> 中定义了可变数量的任务类型,以便我可以定义任务,但不能让它们自动启动。比如说:

Func<Task> task1Func = () => DoTask1Async();
以这种方式定义的一些任务返回值。我需要一种方法将此类任务的结果“传递”给以相同方式定义的后续任务的参数。所以,我想写:
Func<Task> task2Func = () => DoTask2Async(task1Func.Invoke().Result));
问题在于它是 task1Func.Invoke()部分再次启动 task1 任务,这是不好的。
我无法将输入重新定义为链式延续,例如:
Func<Task> funcTasks = () => DoTask1Async().ContinueWith(t => DoTask2Async(t.Result));
因为我需要在代码中知道链中每个任务(即 DoTask1Async/DoTask2Async)完成以运行其他代码的点。另一个问题是我不知道如何计算“链”中涉及多少任务。
我无法在任务完成时存储任务结果,因为任务需要像 task1Func 一样声明性地定义和 task2Func .
任务按定义的顺序处理,每个任务在处理下一个任务之前完成。任务的结果仅用于后续任务。
编辑
使用 task1Func.Invoke().Result 响应对可运行代码的请求这里是。创建一个新的 WPF 项目并向默认网格添加一个按钮。然后清除 MainWindow.xaml.cs 文件并粘贴以下内容。这是最接近我真实项目的代码,同时删除了所有与问题无关的东西。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;

namespace WpfApplication2
{

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        // Declare first task that returns a result
        Func<Task<int>> deferredTask1 = () => DoTask1Async();
        // Declare second task using result of first.
        // BUT this isn't good as it calls deferredTask1 AGAIN, so need another approach.
        Func<Task> deferredTask2 = () => DoTask2Async(deferredTask1.Invoke().Result);

        var item1 = new MyItem() { MyDeferredTask = deferredTask1 };
        var item2 = new MyItem() { MyDeferredTask = deferredTask2 };

        List<MyItem> items = new List<MyItem>();

        items.Add(item1);
        items.Add(item2);

        await DoTasksAsync(items);

    }

    public static async Task<int> DoTask1Async()
    {
        return await Task<int>.Run(() => { return 3000; });
    }

    public static async Task DoTask2Async(int delay)
    {
        await Task.Delay(delay);
    }

    private async Task DoTasksAsync(IEnumerable<MyItem> items)
    {
        foreach (var item in items)
        {
            await item.MyDeferredTask();
        }
    }

    private class MyItem
    {
        public Func<Task> MyDeferredTask { get; set; }
    }
}
}

最佳答案

使用 Microsoft 的 Reactive Framework,您可以执行以下操作:

var query =
    from r1 in Observable.FromAsync(() => DoTask1Async())
    from r2 in Observable.FromAsync(() => DoTask2Async(r1))
    select new { r1, r2 };

await query;

关于c# - 如何将任务结果传递给不使用延续的其他任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40265195/

相关文章:

c# - .Net 中的 Async/await --> 调用没有异步实现的服务方法

javascript - WinRT - 在通用应用程序中启动/注册 IBackgroundTask

c# - 两个线程 - Console.out 的两个流

javascript - Async + ClickBusting + Cordova + Android Galaxy S4 = 意外退出

javascript - 异步函数中的 SetTimeout 和 setInterval

node.js - 如何在 Vscode 的 Typescript 中等待后调试代码?

c# - 代码隐藏文件无法识别 *.ascx 中的控件

c# - Math.NET CryptoRandomSource Next 是有偏差的

asynchronous - Dart 的异步真的是异步吗?

c# - 来自 PCL 的 Xamarin WebAPI 调用