我正在向我的朋友教授async-await关键字,到目前为止,我给了他们一些例子,如下所示。
static async Task Do(Func<Task> job)
{
// some algorithm depends on job parameter.
await job();
}
我认为这个例子在许多情况下实际上很有用。
问题
使用带有Func<Task>
或Func<Task<T>>
类型参数的 void 方法是否有任何用处?据我所知,存在这种方法确实有意义,因为不建议阻止异步方法。随时欢迎任何评论!
Func<Task>
或Func<Task<T>>
类型参数的 void 方法是否有任何用处?
是的。它将是一个与该委托同步执行某些操作的方法。它不会直接执行委托。
我想到的一个例子是异步工作队列要执行的一种Add
方法。委托将在"队列运行器"代码中的其他地方执行。将委托添加到队列将是一个同步操作,即使委托本身是异步的。下面是一个示例。
是的,让非异步方法执行委托可能很有用,例如 .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()));
}