C # ใช้ async lambda expression พร้อม return bool ใน Enumerable นามสกุลทั้งหมด
Sep 28 2020
ฉันมีasyncวิธีการดังต่อไปนี้
private async Task<bool> HasPolicy(AuthorizationFilterContext context, string policy)
{
var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
return authorized.Succeeded;
}
ฉันต้องการใช้ในEnumerable.AllและEnumerable.Anyขยาย
var result1 = IsAndPolicy
? policys.All(async x => await HasPolicy(context, x))
: policys.Any(async x => await HasPolicy(context, x));
แต่รหัสด้านบนได้รับข้อผิดพลาดต่อไปนี้
ข้อผิดพลาด CS4010 ไม่สามารถแปลงนิพจน์ async lambda เป็น delegate type 'Func <string, bool>' นิพจน์แลมบ์ดา async อาจคืนค่าเป็นโมฆะ Task หรือ Task ซึ่งไม่มีการแปลงค่าเป็น 'Func <string, bool>'
คำตอบ
4 00110001 Sep 28 2020 at 15:07
แนวทางหนึ่งคือการฉายภาพไปที่ไฟล์IEnumerable<Task<bool>>
var results = await Task.WhenAll(policys.Select(x => HasPolicy(context, x)));
var result1 = IsAndPolicy
? results.All(x => x)
: results.Any(x => x);
ปัญหาเกี่ยวกับวิธีนี้คือคุณกำลังประมวลผลรายการทั้งหมดโดยไม่จำเป็น
2 PanagiotisKanavos Sep 28 2020 at 15:26
คำตอบไมเคิลแรนดอร์ผลิตผลตรรกะที่ถูกต้อง แต่จะต้องประเมินนโยบายทั้งหมดแม้ว่าในทั้งสองกรณีการประเมินผลที่สามารถลัดวงจรโดยคนแรกที่falseผลสำหรับAllหรือแรกผลสำหรับtrueAny
สิ่งนี้สามารถหลีกเลี่ยงได้โดยการแปลงงานเป็นIAsyncenumerable<T>และใช้System.LinqAsync :
var resultTasks=policies.ToAsyncEnumerable()
.Select(async x => await HasPolicy(context, x));
var result1 = await (IsAndPolicy
? resultTasks.AllAsync(x => x)
: resultTasks.AnyAsync(x => x));