2016-11-20 14 views
0

良い日。 Task func asyncを実行する必要があります。しかし、どのようにこれを行うには?だから、C#:LINQの非同期

public async Task<string> GetPersonForSchedule(int[] usedStaff, string position) 
{ 
    var result = await staffRepository 
     .GetMany() 
     .Where(async elem => await IsGoodPersonForSchedule(elem, usedStaff, position)) 
     .ToListAsync(); 

    return await Task.Factory.StartNew(() => JsonConvert.SerializeObject(result)); 
} 

private async Task<bool> IsGoodPersonForSchedule(Person person, int[] usedStaff, string position) 
{ 
    //... 
    var currPersonFlights = await flightStaffRepository 
     .GetMany() 
     .Include(elem => elem.Flight) 
     .Where(elem => IsDateSuitable(elem.Flight.FlightDate.Value)) 
     .Include(elem => elem.Flight.Route) 
     .ToListAsync(); 
    //... 
    return true; 
} 

、ライン.Where(async elem => await IsGoodPersonForSchedule(elem, usedStaff, position))で私がエラーを持っている:

Cannot convert async lambda expression to delegate type Func<Person, bool> . An async lambda expression may return void, Task or Task, none of which are convertible to Func<Person, bool> .

私は解決策として、これを見つけた: .Where(elem => IsGoodPersonForSchedule(elem, usedStaff, position).Result) しかし、それはとても奇妙で、非同期メソッドのResultプロパティを使用して...それエラーなしでコンパイルします。別の解決策を知っているかもしれませんか?

答えて

-1

Whereは、行が条件を満たすかどうかをアサートできる方法であるため、代わりに値を取得する必要があります。

これは、この.Where(elem => IsGoodPersonForSchedule(elem, usedStaff, position).Result)の解決方法です。

1
private async Task<bool> IsGoodPersonForSchedule(Person person, int[] usedStaff, string position) 
{ 
    //... 
    var currPersonFlights = await flightStaffRepository 
     .GetMany() 
     .Include(elem => elem.Flight) 
     .Where(elem => IsDateSuitable(elem.Flight.FlightDate.Value)) 
     .Include(elem => elem.Flight.Route) 
     .ToListAsync(); 
    //... 
    return true; 
} 

え、いずれかの重要な何かがここに省かビットで行われている、またはこれは単に置き換えることができます。

private Task<bool> IsGoodPersonForSchedule(Person person, int[] usedStaff, string position) 
    => Task.FromResult(true) 

そして、あなたはのタスク一部をプッシュすることはできませんので、これは重要です副問合せへの操作。

あなたは非非同期IsGoodPersonForScheduleおよび非同期IsGoodPersonForScheduleAsyncを持っているしかし、あなたは、クエリ内IsGoodPersonForScheduleを使用することができ、それがデータベースに渡されたクエリ全体の一部になる場合。大規模なクエリの結果を得ることは、全体として非同期になります。

など。

private Task<bool> IsGoodPersonForScheduleAsync(Person person, int[] usedStaff, string position) 
{ 
    return flightStaffRepository 
     .GetMany() 
     .Include(elem => elem.Flight) 
     .Where(elem => IsDateSuitable(elem.Flight.FlightDate.Value)) 
     .AnyAsync(); 
} 

(裕福おそらくですが、私は本当に有意義リポジトリ非同期からブールの結果を得るん何かの例をしたい):のはあなたのIsGoodPersonForScheduleはもっとのようなものだったと仮定しましょう。

あなたも持っていた場合:

private bool IsGoodPersonForSchedule(Person person, int[] usedStaff, string position) 
{ 
    return flightStaffRepository 
     .GetMany() 
     .Include(elem => elem.Flight) 
     .Where(elem => IsDateSuitable(elem.Flight.FlightDate.Value)) 
     .Any(); 
} 

そのフォームは、より広いクエリの一部として使用することができ、そしてそれは、より広い非同期クエリの一部だから、適切な場合、それはまだではなく、SQLに変換されますC#内で非同期で実行されます。

コードの重複は悪いが、解決可能である:

private IQueryable<Flight> FlightsForPerson(Person person, int[] usedStaff, string position) 
{ 
    return flightStaffRepository 
     .GetMany() 
     .Include(elem => elem.Flight) 
     .Where(elem => IsDateSuitable(elem.Flight.FlightDate.Value)); 
} 

private Task<bool> IsGoodPersonForScheduleAsync(Person person, int[] usedStaff, string position) 
=> FlightsForPerson(person, usedStaff, position).AnyAsync(); 

private bool IsGoodPersonForSchedule(Person person, int[] usedStaff, string position) 
=> FlightsForPerson(person, usedStaff, position).Any(); 

私はまた、あなたが持っていることに注意したい:

return await Task.Factory.StartNew(() => JsonConvert.SerializeObject(result)); 

これを実行する必要があり、まだ別のタスクを作成しようとしています以前のawaitを処理するスレッドではなく、別のスレッドで実行します。これは、

return JsonConvert.SerializeObject(result); 
+0

jsonにserializeするためのスレッドの作成について:うん、私はあなたに同意する、新しいスレッドを作成するには、現在のスレッドでこれを実行するよりも時間がかかるはずです。 linqのasyncに関する説明をありがとう。 – Evgeniy175