2016-04-09 41 views
0

Bir depo model yaklaşımı olan bir EF 6 projem var. Benim diğer projedeC# - IQueryable toList Async - EF6

private readonly DbContext _ctx = new SomeDbContext(); 

public IQueryable<TEntity> GetAll(bool noTracking = false) 
{ 
    return !noTracking ? _ctx.Set<TEntity>() : _ctx.Set<TEntity>().AsNoTracking(); 
} 

, o benim kendi ToListAsync uzatma yöntemi yaptık, sadece depo projesi erişmek, işle ilgili ve EntityFramework.dll için herhangi bir referans yoktur.

O T nesnenin IQueryable deposundan dönen alır ve

public static async Task<IList<T>> ToListAsync<T>(this IQueryable<T> query) 
{ 
    return await new Task<IList<T>>(query.ToList); 
} 

Kullanımı T. bir Listesine uyumsuz dönüştürür:

await GetAll(true).Where(<some predicate>).ToListAsync(); 

şeydir, sadece değil iş. Debbuger uzantı yöntemine basıp iletmeye çalıştığında, hata ayıklamayı durdurur, hata yoktur, istisna yoktur, yalnızca uygulamayı tamamen durdurur.

Görevin nasıl oluşturulduğunu değiştirmeyi denedim, ancak ilerleme yok.

Bu neden oluyor?

Teşekkürler.

GÜNCELLEME:

Ben uzatma yöntemi değiştirdik ve görünüşte çalıştı Taşıyamazsınız

, garip bir davranış hala var.

Genişletme yöntemleri yalnızca ben ayrıştırdığımda veya zaman uyumsuz olarak çağırmıyorsa çalışır, serbestçe çalışmasına izin verirse, hata ayıklayıcı/uygulama çıkar, daha fazla kod yürütmez.

İşleri:

Bütün bu testler bir konsol uygulaması yapılan ediliyordu:

var x = repo.GetAll(true).ToListAsync().Result; 

var x = await repo.GetAll(true).ToListAsync(); 

GÜNCELLEME 2 değil işleri (uygulama sadece çıkar) Does Bu nedenle, async yöntemiyle wait gereklidir, aksi halde çıkar.

MethodX().Wait(); 
+0

Neden EF'nin asenkron yöntemlerini depoda kullanmıyorsunuz? –

+0

"IQueryable " işlevinden "Görev >" yerine depo yöntemlerinin dönüş türünü değiştirmem gerekir. İş katmanımda, sorguyu bir listeye ne zaman dönüştüreceğimi ve her zaman bir liste döndürmediğimi seçme esnekliğine sahip olmak istiyorum. Bazen sadece IQueryable'a ihtiyacım var.Ama daha fazla zaman almanın ne olduğunu bilmiyorum: bir veritabanını sorgulamak veya sonuçları bir Listeye yansıtmak. – MurariAlex

cevap

1

Oluşturduğunuz görev başlatılmadı. Önce Start() 'ı çağırmalısınız.

+0

Bu satırı, Task.Run (() => query.ToList()); – MurariAlex

0

Uzantı yöntemini biraz değiştirdim. Neyse ...

Teşekkür

return await Task.Run(() => query.ToList()); 

Anlaşılan o anda çalışıyor ama ben bunu denedim neredeyse eminim.

+0

Gerçekten orada 'Task.Run' kullanmak istemiyorsunuz. Bunun 'ToList'i getirdiğini ne gibi bir avantajı var? –

+0

Veritabanındaki varlıkların (IQueryable -> ToList) materyalizasyonu, "async" i çalıştırmazsa UI iş parçacığını engelleyebilir. Ayrı bir iş parçacığında çalıştırılması gerekiyor. AFAIK, ağır bir operasyon. – MurariAlex

+0

Bu durumda, EF bağımlılığını almanızı ve gerçek zaman uyumsuz yöntemleri kullanmanızı veya yöntemleri eşzamanlı olarak göstermenizi ve * çağıran * kodunun 'Task.Run'unu kullanmasına izin vermenizi öneririm. Şu anda olduğu gibi "sahte eşzamansız" - yani, bir iş parçacığı havuzu üzerinde yalnızca eşzamanlı kod çalıştıran asenkron imzaları olan yöntemler. Konu hakkında bir [kısa blog dizisi] (http://blog.stephencleary.com/2013/10/taskrun-etiquette-and-proper-usage.html) var. –