Multi-async dalam Entity Framework 6?

87

Ini kode saya:

var banner = context.Banners.ToListAsync()
var newsGroup = context.NewsGroups.ToListAsync()
await Task.WhenAll(banner, newsGroup);

Tetapi ketika saya memanggil fungsi dari pengontrol. Itu menunjukkan kesalahan

Operasi kedua dimulai pada konteks ini sebelum operasi asinkron sebelumnya selesai. Gunakan 'await' untuk memastikan bahwa semua operasi asinkron telah selesai sebelum memanggil metode lain dalam konteks ini. Setiap anggota instance tidak dijamin aman untuk thread.

Tolong bantu saya mengatasi masalah ini.

Sebuah Hv
sumber
Saya punya 2 tugas. Jika saya menjalankan setiap tugas. itu sukses. tetapi jika saya menjalankan seperti kode saya di atas. Ini kesalahan
Sebuah Hv

Jawaban:

119

Pengecualian menjelaskan dengan jelas bahwa hanya ada satu operasi asinkron per konteks yang diperbolehkan dalam satu waktu.

Jadi, Anda harus melakukannya awaitsatu per satu seperti yang disarankan pesan kesalahan:

var banner = await context.Banners.ToListAsync();
var newsGroup = await context.NewsGroups.ToListAsync();

Atau Anda dapat menggunakan banyak konteks:

var banner = context1.Banners.ToListAsync();
var newsGroup = context2.NewsGroups.ToListAsync();
await Task.WhenAll(banner, newsGroup);
Stephen Cleary
sumber
35
hanya sebuah catatan, jika Anda memiliki variabel Lazy yang menggunakan konteks dalam kueri bahkan dengan await itu akan menimbulkan kesalahan yang sama, cukup dapatkan properti sebelum kueri, itu menyakitkan untuk mengetahuinya.
Pedro.The.Kid
7
@ Pedro.The.Kid: Sebagai aturan umum, jangan gunakan lazy loading dengan akses DB asynchronous. Pemuatan lambat selalu sinkron, jadi jauh lebih baik menggunakan kueri Sertakan atau pisahkan untuk data tambahan.
Stephen Cleary
1
Apakah ada alasan khusus mengapa Anda memerlukan konteks per kueri asinkron? Saya merasa ini menjadi faktor pembatas.
Zapnologica
1
@Zapnologica: Seperti itulah ES6 dirancang. Setiap konteks hanya dapat menangani satu kueri dalam satu waktu . Jadi jika Anda menyelesaikan satu kueri sebelum kueri berikutnya dimulai, Anda hanya memerlukan satu konteks. Ini hanya masalah jika Anda ingin melakukan banyak kueri pada saat yang bersamaan.
Stephen Cleary
@StephenCleary, Saya mengalami kesulitan menemukan kueri itu karena saya tidak ada apa pun sebelum pengecualian. Adakah cara bagi kita untuk menemukan apa yang sedang dieksekusi? Terima kasih
Fabio Milheiro
3

Jika Anda menggunakan Unity untuk injeksi ketergantungan dengan misalnya pola repositori, Anda akan mendapatkan kesalahan berikut menggunakan dua atau lebih konteks dengan buat / perbarui / hapus:

Hubungan antara dua objek tidak dapat ditentukan karena mereka dilampirkan ke objek ObjectContext yang berbeda.

Ini bisa diselesaikan dengan menggunakan PerRequestLifetimeManager. Info lebih lanjut di sini:

C # EF6 membuat beberapa panggilan asinkron ke satu konteks menggunakan Unity - Asp.Net Web Api

container.RegisterType<DbContext>(new PerRequestLifetimeManager());
container.RegisterType<ISupplierRepository, SupplierRepository>();
container.RegisterType<IContactRepository, ContactRepository>();
Ogglas
sumber