3 回答

TA貢獻1825條經驗 獲得超4個贊
首先,您需要使您的方法異步。這意味著他們必須返回一個任務。例如:
public static async Task Foo()
{
await Task.Delay(1);
Console.WriteLine("Foo!");
}
public static async Task Bar()
{
await Task.Delay(1);
Console.WriteLine("Bar!");
}
然后要將它們放入列表中,您必須將列表定義為包含正確的類型。由于異步方法實際上返回了一些東西,所以它是一個 Func,而不是一個動作。它返回一個任務。
var actions = new List<Func<Task>>
{
Foo, Bar
};
要調用它們,請在列表中選擇(使用 Linq)來調用它們。這將創建一個任務列表來代替功能列表。
var tasks = actions.Select( x => x() );
然后等待他們:
await Task.WhenAll(tasks);
完整示例:
public static async Task MainAsync()
{
var actions = new List<Func<Task>>
{
Foo, Bar
};
var tasks = actions.Select( x => x() );
await Task.WhenAll(tasks);
}
輸出:
Foo!
Bar!
DotNetFiddle 上的示例
如果你的方法返回一個布爾值,那么返回類型就變成Task<bool>了,其余的也一樣:
public static async Task<bool> Foo()
{
await Task.Delay(1);
Console.WriteLine("Foo!");
return true;
}
public static async Task<bool> Bar()
{
await Task.Delay(1);
Console.WriteLine("Bar!");
return true;
}
var actions = new List<Func<Task<bool>>>
{
Foo, Bar
};
var tasks = actions.Select( x => x() );
await Task.WhenAll(tasks);
在等待它們之后,您可以使用另外一條 LINQ 語句將任務轉換為它們的結果:
List<bool> results = tasks.Select( task => task.Result ).ToList();

TA貢獻1871條經驗 獲得超8個贊
根據評論:
但是,我的任務需要每個方法調用的布爾值,因為無論服務是否關閉,我都必須向前端報告狀態
為將返回所需布爾值的方法創建一個包裝器方法
public async Task<Result> Check(string name, Func<Task> execute)
{
try
{
await execute();
return new Result(name, true, string.Empty);
}
catch (Exception ex)
{
return new Result(name, false, ex.Message);
}
}
public class Result
{
public string Name { get; }
public bool Success { get; }
public string Message { get; }
public Result(string name, bool success, string message)
=> (Name, Success, Message) = (name, success, message);
}
然后您不需要收集代表,而是收集Task.
var tasks = new[]
{
Check(nameof(details.GetEmployer), () => details.GetEmployer(Id)),
Check(nameof(accounts.GetAccountStatus), () => accounts.GetAccountStatus(Id)),
};
var completed = await Task.WhenAll(tasks);
foreach (var task in completed)
{
Console.WriteLine($"Task: {task.Name}, Success: {task.Success};");
}

TA貢獻1780條經驗 獲得超1個贊
我想你只是在尋找像這樣簡單的東西?
var myList = new List<Action>()
{
async() => { await Foo.GetBarAsync(); },
...
};
我建議您將類型從更改Action為Func<Task>喜歡。
var myList = new List<Func<Task>>()
{
async() => { await Foo.GetBarAsync(); },
};
您可以在此處閱讀有關原因的更多信息:https ://blogs.msdn.microsoft.com/pfxteam/2012/02/08/potential-pitfalls-to-avoid-when-passing-around-async-lambdas/
調用(簡化)
foreach (var action in myList)
{
await action.Invoke();
}
- 3 回答
- 0 關注
- 118 瀏覽
添加回答
舉報