Multi-async trong Entity Framework 6?


87

Đây là mã của tôi:

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

Nhưng khi tôi gọi hàm từ bộ điều khiển. Nó cho thấy lỗi

Thao tác thứ hai bắt đầu trên ngữ cảnh này trước khi hoàn thành thao tác không đồng bộ trước đó. Sử dụng 'await' để đảm bảo rằng mọi hoạt động không đồng bộ đã hoàn thành trước khi gọi một phương thức khác trên ngữ cảnh này. Bất kỳ thành viên thể hiện nào đều không được đảm bảo an toàn cho chuỗi.

Xin hãy giúp tôi giải quyết vấn đề này.


Tôi có 2 nhiệm vụ. Nếu tôi chạy từng tác vụ. đó là thành công. nhưng nếu tôi chạy như mã của tôi ở trên. Đó là lỗi
Hv

Câu trả lời:


119

Ngoại lệ giải thích rõ ràng rằng chỉ có một hoạt động không đồng bộ cho mỗi ngữ cảnh được phép tại một thời điểm.

Vì vậy, bạn phải làm awaittừng cái một như thông báo lỗi gợi ý:

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

Hoặc bạn có thể sử dụng nhiều ngữ cảnh:

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

33
chỉ cần lưu ý, nếu bạn có một biến Lazy sử dụng ngữ cảnh trong truy vấn ngay cả khi đang chờ nó sẽ gây ra lỗi tương tự, chỉ cần lấy thuộc tính trước truy vấn, thật khó để tìm ra điều này.
Pedro.The.Kid

7
@ Pedro.The.Kid: Theo nguyên tắc chung, không sử dụng tính năng tải chậm với quyền truy cập DB không đồng bộ. Quá trình tải chậm luôn đồng bộ, vì vậy tốt hơn hết bạn nên sử dụng Truy vấn bao gồm hoặc tách biệt cho dữ liệu bổ sung.
Stephen Cleary

1
Có lý do cụ thể nào khiến bạn cần ngữ cảnh cho mỗi truy vấn không đồng bộ không? Tôi cảm thấy như điều này trở thành một yếu tố hạn chế.
Zapnologica

1
@Zapnologica: Đó chỉ là cách ES6 được thiết kế. Mỗi ngữ cảnh chỉ có thể xử lý một truy vấn tại một thời điểm . Vì vậy, nếu bạn hoàn thành một truy vấn trước khi truy vấn tiếp theo bắt đầu, bạn chỉ cần một ngữ cảnh. Nó chỉ là một vấn đề nếu bạn muốn thực hiện nhiều truy vấn cùng một lúc.
Stephen Cleary

@StephenCleary, tôi gặp khó khăn khi tìm truy vấn đó vì tôi không có bất kỳ thứ gì ngay lập tức trước ngoại lệ. Có cách nào để chúng tôi tìm thấy những gì hiện đang được thực thi không? Cảm ơn
Fabio Milheiro


3

Nếu bạn sử dụng Unity để tiêm phụ thuộc với ví dụ mẫu kho lưu trữ, bạn sẽ gặp lỗi sau khi sử dụng hai hoặc nhiều ngữ cảnh với tạo / cập nhật / xóa:

Không thể xác định mối quan hệ giữa hai đối tượng vì chúng được gắn vào các đối tượng ObjectContext khác nhau.

Điều này có thể được giải quyết bằng cách sử dụng PerRequestLifetimeManager. Thông tin thêm tại đây:

C # EF6 thực hiện nhiều lệnh gọi không đồng bộ đến một ngữ cảnh bằng Unity - Asp.Net Web Api

container.RegisterType<DbContext>(new PerRequestLifetimeManager());
container.RegisterType<ISupplierRepository, SupplierRepository>();
container.RegisterType<IContactRepository, ContactRepository>();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.