C # menggunakan ekspresi lambda asinkron dengan return bool di ekstensi Enumerable.All

Sep 28 2020

Saya memiliki asyncmetode berikut

private async Task<bool> HasPolicy(AuthorizationFilterContext context, string policy)
{
    var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
    return authorized.Succeeded;
}

Saya ingin menggunakannya dalam Enumerable.Alldan Enumerable.Anyekstensi

var result1 = IsAndPolicy
    ? policys.All(async x => await HasPolicy(context, x))
    : policys.Any(async x => await HasPolicy(context, x));

Tetapi kode di atas mendapatkan kesalahan berikut

Kesalahan CS4010 Tidak dapat mengonversi ekspresi lambda asinkron ke tipe delegasi 'Func <string, bool>'. Ekspresi lambda asinkron dapat mengembalikan void, Task atau Task, tidak ada satupun yang dapat diubah menjadi 'Func <string, bool>'.

Jawaban

4 00110001 Sep 28 2020 at 15:07

Salah satu pendekatannya adalah memproyeksikan keIEnumerable<Task<bool>>

var results = await Task.WhenAll(policys.Select(x => HasPolicy(context, x)));

var result1 = IsAndPolicy 
   ? results.All(x => x)                
   : results.Any(x => x);

Masalah dengan pendekatan ini, adalah Anda memproses semua item yang berpotensi tidak perlu.

2 PanagiotisKanavos Sep 28 2020 at 15:26

Jawaban Michael Randall menghasilkan hasil logis yang benar tetapi harus mengevaluasi semua kebijakan, meskipun dalam kedua kasus evaluasi tersebut dapat dihubung pendek, oleh falsehasil pertama untuk All, atau truehasil pertama untuk Any.

Ini dapat dihindari dengan mengubah tugas menjadi IAsyncenumerable<T>dan menggunakan System.Linq.Async :

var resultTasks=policies.ToAsyncEnumerable()
                        .Select(async x => await HasPolicy(context, x));

var result1 = await (IsAndPolicy 
                       ? resultTasks.AllAsync(x => x)                
                       : resultTasks.AnyAsync(x => x));