我正在向朋友们教授async-await关键字,到目前为止,我给他们提供了一些示例,如下所示。
static async Task Do(Func<Task> job)
{
// some algorithm depends on job parameter.
await job();
}
我认为该示例在许多情况下都非常有用。
使用类型为Func<Task>
或Func<Task<T>>
的参数的void方法是否有用?据我认为,存在这种方法确实有意义,因为不建议使用阻塞异步方法。随时欢迎任何评论!
答案 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()));
}