Chúng tôi đang sử dụng Nhà cung cấp phiên ngoài quy trình (ScaleOut) cho ứng dụng ASP.NET và chúng tôi nhận thấy rằng khi một đối tượng không được thiết lập chính xác để hủy tuần tự hóa. nó sẽ cuối cùng khiến toàn bộ quá trình chấm dứt.Làm thế nào để bảo vệ các hồ bơi ứng dụng khỏi các trường hợp ngoại lệ tuần tự hóa phiên?
Sao chép và xử lý trường hợp này là nơi nó trở nên thú vị hơn.
Trường hợp ngoại lệ mà chấm dứt quá trình trên được nêu ra trong AnyStaObjectsInSessionState mà thực hiện khá đơn giản:
internal static bool AnyStaObjectsInSessionState(HttpSessionState session)
{
if (session != null)
{
int count = session.Count;
for (int i = 0; i < count; i++)
{
object obj2 = session[i];
if (((obj2 != null) && (obj2.GetType().FullName == "System.__ComObject"))
&& (UnsafeNativeMethods.AspCompatIsApartmentComponent(obj2) != 0))
{
return true;
}
}
}
return false;
}
Dưới đây là stack trace cho thấy cách ngoại lệ ở đây chấm dứt quá trình:
An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/1/ROOT
Process ID: 4208
Exception: System.Runtime.Serialization.SerializationException
Message: The constructor to deserialize an object of type 'Lucene.Net.QueryParsers.ParseException' was not found.
StackTrace: at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader reader)
at System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert()
at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(String name, Boolean check)
at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(Int32 index)
at System.Web.SessionState.SessionStateItemCollection.get_Item(Int32 index)
at System.Web.SessionState.HttpSessionStateContainer.get_Item(Int32 index)
at System.Web.Util.AspCompatApplicationStep.AnyStaObjectsInSessionState(HttpSessionState session)
at System.Web.HttpApplicationFactory.FireSessionOnEnd(HttpSessionState session, Object eventSource, EventArgs eventArgs)
at System.Web.SessionState.SessionOnEndTargetWorkItem.RaiseOnEndCallback()
at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
InnerException: System.Runtime.Serialization.SerializationException
Message: The constructor to deserialize an object of type 'Lucene.Net.QueryParsers.ParseException' was not found.
StackTrace: at System.Runtime.Serialization.ObjectManager.GetConstructor(Type t, Type[] ctorParams)
at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
Chúng tôi muốn hiểu hai điều:
Khi nào FireSessionOnEnd lửa cho nhà cung cấp ngoài quy trình và, quan trọng hơn, làm cách nào chúng ta có thể bắt chước điều này trong môi trường phát triển không được tải? Tôi đã thử nghiệm với thời gian chờ phiên giảm xuống (đặt thành một phút), tự gọi Abandon() và tự gọi GC.Collect(), tất cả đều không có kết quả.
Chúng tôi có thể bẫy lỗi xảy ra ở bước này để bảo vệ hồ bơi ứng dụng không? Các ngoại lệ được nêu ở đây được ghi lại w/Nguồn = ASP.NET 2.0.50727.0 và không đạt được trình xử lý lỗi ứng dụng trong global.asax. Những gì chúng ta có thể làm để bảo vệ chống lại kịch bản này, ngay cả sau khi kiểm tra thích hợp & số dư được áp dụng cho các đối tượng ràng buộc phiên?
Mọi thông tin chi tiết sẽ được đánh giá cao.
Có thể họ nên sửa mã của họ để không cho phép ngoại lệ serialziation làm hỏng AppDomain. Chỉ là một ý nghĩ. –
Đó là một suy nghĩ tốt, và tôi nghĩ rằng họ đồng ý; đó là một kịch bản cực kỳ hiếm nhưng một trong đó nên được bảo vệ chống lại dù sao. – Nariman
@ John: Có vẻ như anh ấy đang sử dụng Lucene.net. Mặc dù nó là một ứng dụng của bên thứ 3, AFAIK, nguồn mở của nó và anh ta nên đánh dấu lớp vi phạm 'Serializable' – ram