C#如何将T的动作转换为T的任务的等待功能

时间:2018-09-17 11:18:06

标签: c# async-await delegates func

我希望能够将一些方法保存为动作及其对应的异步对应物。为此,我需要将它们变成Func<Task>

我已经开始工作了。

public class Class1 {
    Action myAction;
    Func<Task> myFunc;

    public Class1() {
        // for demo purposes I use a local method
        void MyVoidMethod() {
            // some code
        }
        myAction = MyVoidMethod;
        myFunc = () => Task.Factory.StartNew(myAction);
    }

    public async void AnotherMethod() {
        // later in async some method
        await myFunc.Invoke();
    }
}

但是当我还想拥有一个可选的输入参数(例如,报告异步Func的进度)时如何声明呢?我不知道该语法如何工作。

public class Class2 {
    Action<IProgress<bool>> myAction;
    Func<Task<IProgress<bool>>> myFunc;

    public Class2() {
        void MyVoidMethod(IProgress<bool> prog = null) {
            // some code
        }
        myAction = MyVoidMethod;
        // line below gives squiggelies under `myAction`
        myFunc = () => Task.Factory.StartNew(myAction);
    }

    public async void AnotherMethod() {
        // later in async some method
        var prog = new Progress<bool>();
        prog.ProgressChanged += (s, e) => {
            // do something with e
        };
        await myFunc.Invoke(prog);
    }
}

1 个答案:

答案 0 :(得分:1)

您要定义myFunc接受一个Task而不是返回一个Task,您需要定义func接受IProgress并返回一个Task作为结果。

var recipes = [
{
    'name': 'Omelette',
    'ingredients': [
        "Eggs",
        "Mushrooms",
        "Peppers",
        "Onions"
    ]
},
{
    'name': 'Spaghetti',
    'ingredients': [
        "Pasta",
        "Tomato",
        "Meat Balls"
    ]
}];

var storedIngredients = ["Pasta",
        "Tomato",
        "Meat Balls",
        "Onions"];

var match = recipes.filter(x => x.ingredients.every(e => storedIngredients.some(s => s === e)));

console.log(match);

然后,您需要将进度传递给lambda中的执行方法

Func<IProgress<bool>, Task> myFunc;

您的AnotherMethod需要将Progress in作为参数

this.myFunc = p => Task.Factory.StartNew(() => this.MyVoidMethod(p))