具有Func <task>或Func <task <t >>参数的同步void方法实际上有用吗?

时间:2019-05-29 09:34:41

标签: c#

我正在向朋友们教授async-await关键字,到目前为止,我给他们提供了一些示例,如下所示。

static async Task Do(Func<Task> job)
{
    // some algorithm depends on job parameter.
    await job();
} 

我认为该示例在许多情况下都非常有用。

问题

使用类型为Func<Task>Func<Task<T>>的参数的void方法是否有用?据我认为,存在这种方法确实有意义,因为不建议使用阻塞异步方法。随时欢迎任何评论!

2 个答案:

答案 0 :(得分:1)

  

使用参数类型为Func<Task>Func<Task<T>>的void方法是否有用?

是的。这将是一种与该委托同步执行某些操作的方法。它不会直接执行委托。

想到的一个示例是一种Add方法,用于执行异步工作队列。该委托将在“队列运行器”代码中的其他位置执行。即使委托本身是异步的,将委托添加到队列也将是同步操作。 Here's an example

答案 1 :(得分:0)

是的,可以使用非异步方法来执行委托,例如,.Net提供的LINQ查询。

有时您希望应用程序被阻塞,直到被调用者返回特定结果为止。

让我们以List.ForEach(Action)方法为例。

(注意:这不是,实际的实现是在.Net中!)

public void ForEach(Action<T> action) {
    if (action is default(Action<T>))
        throw new ArgumentNullException(nameof(action), "Action must not be null!");

    foreach (var element in this) {
        // Execute provided action (delegate)
        action(T);

    }
}

在这种情况下,由于例如线程安全性,您希望循环同步运行。


另一个示例是public static System.Collections.Generic.IEnumerable<TSource> Where<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,bool> predicate);方法,出于线程安全原因,该方法也将同步运行,因此您的结果将按预期返回。

如果需要,您还可以始终从单独的线程(或异步方法)中调用方法。大多数控制台应用程序都是同步运行的,因为没有GUI需要响应。


编辑

以Func作为参数的同步方法的另一个示例是控制台应用程序。假设您正在实现具有库依赖项(您无法控制)的控制台应用程序。该库仅公开任务。 在控制台应用程序中,您通常不使用/不需要异步应用程序,因为没有可以阻塞的GUI和/或您的应用程序只能在用户提供输入后才能继续。

// External method returning a Task
public Task<int> DoFooAsync(object myParam);

public bool ParseMyFoo(Func<Task<int>> myTask) {
    var result = myTask().Result;

    if (result == 0xbadbeef || result == 0xf00dbabe) {
        Console.WriteLine("Schrödingers takeaway");
    }
}

public static void Main(string[] args) {
    Console.WriteLine("Assesment: {0}", ParseMyFoo(DooFooAsync(Console.ReadLine()));
}