2010-03-21 20 views
18

Một cách để tăng khả năng mở rộng của ứng dụng máy chủ là chạy hoạt động liên kết IO (đọc tệp, ổ cắm, yêu cầu web, yêu cầu cơ sở dữ liệu, v.v.) không đồng bộ. Điều này không có nghĩa là chạy chúng trong ThreadPool mà sẽ chỉ chặn các luồng trong khi thao tác đang được thực hiện. Cách chính xác là sử dụng API không đồng bộ (BeginRead, BeginGetResponse, BeginExecuteReader, v.v.). Vấn đề cũng được mô tả trong cuốn sách CLR vi C#.Làm cách nào để chạy các truy vấn NHibenate không đồng bộ?

Dưới đây là một số bài viết về asynchronous queries in Linq to SQL.

Có cách nào để thực thi truy vấn Nhibernate một cách đồng bộ không? Điều gì về Linq để NHibernate?

Cảm ơn bạn, Andrey

+0

hỗ trợ 'async' đang chuyển sang NHibernate 4.2.0 và 5.0.0. https://nhibernate.jira.com/browse/NH-3971 –

Trả lời

9

Thật không may, không. NHibernate không phơi bày việc thực thi nội bộ của lệnh thực thi theo cách mà L2S thực hiện.

Bạn sẽ phải sử dụng trình tạo luồng hoặc tạo bản vá cho NH để thêm hỗ trợ truy vấn không đồng bộ. Điều đó sẽ rất được hoan nghênh bởi cộng đồng và sẽ tạo nên một bài tập tốt đẹp (nhưng nó không tầm thường chút nào)

+0

Tương lai + 1 tác vụ thực hiện nó khá độc đáo cho tất cả các cơ sở dữ liệu không? MARS (cần thiết cho nhiều cuộc gọi không đồng bộ) không được hỗ trợ (và thực sự cần thiết?) Bởi một số cơ sở dữ liệu sql – Firo

+0

Tương lai không bắt đầu thực hiện. Chúng chỉ là một trình bao bọc trên nhiều tính năng. –

+0

Tôi biết điều đó. Đó là lý do tại sao tôi đã viết "+ nhiệm vụ". Xem câu trả lời của tôi dưới đây cho những gì tôi có nghĩa là – Firo

12

Lưu ý rằng các cuộc gọi cơ sở dữ liệu không đồng bộ KHÔNG ngụ ý khả năng mở rộng tổng thể tốt hơn. Tôi khuyên bạn nên đọc bài viết "Should my database calls be Asynchronous?" để có phân tích chuyên sâu. Dưới đây là một trích dẫn từ bài viết rằng:

Một tôn trọng DB kiến ​​trúc sư/Web đã đi xa hơn khi nói:
Đối với cơ sở dữ liệu ứng dụng sử dụng các hoạt động async để giảm số lượng các chủ đề chặn trên máy chủ web được hầu như luôn luôn là hoàn toàn lãng phí thời gian. Máy chủ web nhỏ có thể dễ dàng xử lý theo cách yêu cầu chặn đồng thời hơn cơ sở dữ liệu của bạn back-end có thể xử lý đồng thời. Thay vào đó, hãy đảm bảo rằng các cuộc gọi dịch vụ của bạn có giá rẻ tại cơ sở dữ liệu và giới hạn số lượng đồng thời thực hiện các yêu cầu đến số mà bạn đã thử nghiệm để làm việc một cách chính xác và tối đa hóa thông lượng giao dịch tổng thể .

+8

đối số này đã trở thành không hợp lệ kể từ tháng 8 năm 2012 (sau .net 4,5 rtm). bây giờ mà chi phí của mã async đã được giảm đáng kể nó là absolutelly ok để viết các hoạt động db theo cách không đồng bộ. nhưng tại thời điểm này, vẫn chưa có hỗ trợ trong NHibernate. Hy vọng rằng điều này sẽ được tuyên bố sớm thôi :) –

+9

@BorisBucha .NET 4.5 không liên quan gì đến điều này. Chỉ vì bạn có thể dễ dàng thể hiện mã async trong mã C# của bạn không có nghĩa là máy chủ web và cơ sở dữ liệu tự động mở rộng hơn. –

+6

tôi tin điều đó. chắc chắn bạn không thể làm cho DB của bạn nhanh hơn chỉ bằng cách gọi nó theo cách không đồng bộ nhưng máy chủ web của bạn dễ dàng hơn nhiều để mở rộng theo chiều dọc. Ít chủ đề có nghĩa là ít bộ nhớ hơn. Nếu tôi có thể phóng đại quá nhiều chủ đề tôi có thể nói rằng bằng cách tận dụng không đồng bộ, bạn * luôn luôn * giành chiến thắng. Hiệu suất vẫn giữ nguyên trong trường hợp xấu nhất. Trong trường hợp tốt nhất bạn có thể cải thiện nó đáng kể chỉ bằng cách cấm các nhiệm vụ io-bound để chiếm Threadpool. Và chi phí phát triển là hầu như không có gì vì vậy tôi không thấy bất kỳ lý do không làm tất cả mọi thứ trong async-cách bắt đầu từ .net4.5. –

1

Mặc dù vẫn không có hỗ trợ cho truy vấn không đồng bộ trong NH, bạn vẫn có thể khắc phục một phần tác động không mong muốn của các cuộc gọi db chạy dài (chạy dài) từ chuỗi yêu cầu.

Điều bạn muốn là chia Threadpool giữa các hoạt động ngắn và dài hạn. Tất nhiên điều này là không thể với việc thực hiện thực tế của Threadpool và TPL nhưng bạn có thể giúp mình khá eassilly bằng cách viết hàng đợi của riêng bạn Sản xuất/tiêu dùng với các mặt hàng awaitable và tùy chỉnh concurency.

hãy có một cái nhìn vào ví dụ tôi đã đặt lại với nhau: https://gist.github.com/3746240

Mã được sao chép/dán từ cuốn sách tuyệt vời "C# 5.0 in a Nutshell: Các tham chiếu Definitive" bởi Joseph Albahari và Ben Albahari với sửa đổi được thực hiện bởi tôi khiến cho trình lên lịch tạo ra các chuỗi công việc chuyên dụng cho các mục proccesing.

+0

FYI, hãy nhớ rằng Threadpool (và "chờ đợi Task.StartNew (...)" trong hệ quả) có tính năng tự động phát triển khi tải nặng, bạn có thể kết thúc với nhiều chủ đề chuyên dụng và điều này có thể là giải pháp mong muốn hơn. Tôi tin rằng nó có thể hữu ích trong một số trường hợp (nếu bạn đo rò rỉ perf gây ra bởi chậm autogrow chính nó :)) –

11

nhiều cuộc gọi async thể được viết lại với Futures

var footask = QueryFooAsync(); 
var bartask = QueryBarAsync(); 
var baztask = QueryBazAsync(); 

var foos = await footask; 
var bars = await bartask; 
var baz = await baztask; 

// do something with foos, bars, baz 

có thể được thay thế bằng

var foos = session.Query<Foo>().....ToFuture(); 
var bars = session.Query<Bar>().....ToFuture(); 
var baz = session.Query<Bazes>().....ToFutureValue(); 

await Task.Factory.StartNew(() => var ignored = baz.Value) // await the results 

// do something with foos, bars, baz 

này thậm chí còn có lợi ích trên mã async rằng thời gian khứ hồi chỉ được thanh toán một lần thay vì 3 lần .

+1

Điều này là không đúng sự thật hoạt động async và tôi sẽ không đề nghị làm điều đó bởi vì bây giờ bạn chỉ đang tạo ra một chủ đề khác. Bắt đầu nhiệm vụ mới có thể có lợi nếu bạn muốn tải công việc ràng buộc cpu để tách luồng, nhưng cuộc gọi db là hoạt động I/O và nó hoạt động tốt nhất với api không đồng bộ. –

+0

@AndzejMaciusovic Bạn nói rằng nó không thực sự không đồng bộ như giải phóng luồng nhưng nó chặn chuỗi ngắn hơn nhiều (1 vòng thay vì 3) và có thể làm nhẹ tải trên cơ sở dữ liệu vì nó chỉ xử lý 1 Yêu cầu (với 3 truy vấn) . Xem câu trả lời của Mauricio Scheffer về lý do tại sao việc tiết kiệm CPU có thể không giúp ích nhiều cho điều đó. – Firo

Các vấn đề liên quan