2015-10-26 18 views
6

ASP.NET được biết là triển lãm những gì được gọi là "chủ đề nhanh nhẹn". Trong ngắn hạn, nó có nghĩa là nhiều luồng có thể được sử dụng để thực hiện một yêu cầu duy nhất, mặc dù không nhiều hơn một luồng tại một thời điểm. Đây là một tối ưu hóa có nghĩa là một chuỗi chờ I/O không đồng bộ có thể được trả về hồ bơi và được sử dụng để phục vụ các yêu cầu khác.Chủ đề nhanh nhẹn trong ASP.NET - cách khắc phục?

Tuy nhiên, ASP.NET không di chuyển tất cả dữ liệu liên quan đến chuỗi khi di chuyển một yêu cầu. Microsoft hoặc quên làm như vậy, hoặc nghĩ rằng sử dụng lưu trữ thread-local (được thực hiện dễ dàng bởi các thuộc tính ThreadStatic) là một cái gì đó chỉ những người mã hóa ASP.NET mình nên làm.

Dựa trên googling nhanh chóng, có vẻ như với tôi rằng cách duy nhất để tránh vấn đề là dựa vào HttpContext thay thế. Ngữ cảnh thực sự được di chuyển nếu ASP.NET quyết định chuyển chủ đề giữa yêu cầu, vì vậy điều này khắc phục được vấn đề. Nhưng nó tạo ra một thương hiệu mới đau đầu thay vì: Nó ràng buộc logic ứng dụng của bạn để HttpContext, và do đó đến một bối cảnh web. Điều đó không thể chấp nhận được trong mọi tình huống (trên thực tế, tôi muốn nói nó không thể chấp nhận được trong hầu hết). Bên cạnh đó, vì HttpContext được niêm phong và có các hàm tạo nội bộ, bạn không thể giả lập hoặc khai báo nó, và do đó logic của bạn cũng trở nên không thể thực hiện được.

Theo this (old) blog post, CallContext KHÔNG hoạt động, điều này khá tức giận vì ngữ cảnh cuộc gọi chính xác là một chuỗi logic!

Có cách nào đơn giản để thực hiện một cách đáng tin cậy cách ly "per-LOGICAL-thread" sẽ hoạt động trong ngữ cảnh asp.net cũng như các ngữ cảnh khác không?

Nếu không, có ai biết khung công tác nhẹ của bên thứ ba giải quyết được sự cố không? StructureMap có hoạt động đúng khi ASP.NET di chuyển luồng không?

Tôi muốn có câu trả lời chung, nhưng trong trường hợp có ai đó thắc mắc, trường hợp sử dụng cụ thể mà tôi đang xem là sử dụng khung Entity trong ngữ cảnh SharePoint. Chúng tôi không may bị mắc kẹt với SP-2010 và EF 3.5 trong một thời gian. EF về cơ bản yêu cầu dữ liệu được lưu bằng cách sử dụng cùng một bối cảnh như ban đầu chúng được đọc từ - hoặc người nào khác bạn phải tự theo dõi các thay đổi. Tôi muốn giới thiệu một khái niệm "mô hình hiện tại". Lần đầu tiên mô hình được gọi khi xử lý mỗi yêu cầu HTTP, nó sẽ được khởi tạo, và sau đó cùng một cá thể mô hình đó sẽ được sử dụng trong suốt thời gian yêu cầu. Nhưng mã dựa vào "Model.Current" nên cũng hoạt động nếu được thực hiện trong ngữ cảnh của công việc hẹn giờ. Tôi tốt với mã công việc hẹn giờ một cách rõ ràng xử lý các mô hình khi thực hiện với nó (một nhiệm vụ tôi muốn cung cấp cho một xử lý cho HttpApplication.EndRequest trong bối cảnh web SharePoint). Có thể có lý do để không làm điều này, và điều đó cũng thú vị, nhưng tôi sẽ anyway thực sự đánh giá cao để tìm hiểu cách để đạt được "cách ly chuỗi logic" trong ngữ cảnh asp.net, vì nó sẽ là hữu ích đáng kể.

+0

Bạn đang nói về trình xử lý async trong asp.net, phải không? Bởi vì asp.net mặc định là ** không ** không đồng bộ nên mọi yêu cầu được xử lý bởi một luồng I/O chặn đơn. Trong trường hợp xử lý async, bạn có thể khai báo giao diện 'IWhateverContext' của riêng mình và bọc HttpContext bởi một lớp thực hiện, nếu bạn muốn tách logic của bạn khỏi HttpContext. –

+0

Không, tôi đang nói về bất kỳ mã asp.net trơn-vanilla nào. Rất nhiều mã .NET framework sử dụng async I/O dưới mui xe (tuyệt vời), và các yêu cầu được di chuyển sang các luồng mới có thể xảy ra trong bất kỳ ứng dụng asp.net thông thường nào (* sẽ * được, nếu tất cả các khía cạnh của luồng đã được di chuyển chính xác để nó trong suốt và không ngẫu nhiên phá vỡ nội dung). –

+0

Btw, làm thế nào để * gói * HttpContext decouple từ nó? Sự phụ thuộc sẽ vẫn còn đó, và nó sẽ sụp đổ bất cứ khi nào không có HttpContext hiện tại - chẳng hạn như trong một công việc hẹn giờ, nếu bạn sử dụng cùng một lớp nghiệp vụ cho một ứng dụng di động, các cửa sổ biểu mẫu hoặc ứng dụng WPF, vân vân. –

Trả lời

0

Có bài đăng thú vị liên quan đến sự cố: Implicit Async Context ("AsyncLocal").

Nếu tôi có mọi thứ đúng, logic CallContext ví dụ CallContext.LogicalGetDataCallContext.LogicalSetData làm cho nó thực sự để di chuyển dữ liệu không thay đổi được một cách chính xác bạn sống trong thế giới thời gian qua .NET 4.5. Giới hạn immutable này là một hạt nhưng vẫn còn ... cách để đi.

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