2008-11-16 25 views
6

Có thể bắt sự kiện tái chế trong global.asax không?IIS Recycle Global.asax

Tôi biết Application_End sẽ được kích hoạt nhưng có cách nào để biết rằng nó đã được kích hoạt bởi một tái chế của hồ bơi ứng dụng?

thx, Lieven Cardoen aka Johlero

+0

App Recycle có thể là một mối quan hệ khá tàn bạo tùy thuộc vào tình trạng của quá trình của bạn - kịch bản tồi tệ nhất là Win32 :: TerminateProcess được gọi. Không có cách nào để bẫy một kết quả như vậy trong quá trình của bạn. Bạn đang cố gắng đạt được điều gì? Flushing một số nhà nước? – stephbu

Trả lời

3

Vì vậy, đây là ý tưởng về cách thức hoạt động của tính năng này.

Dựa trên tôi previous answer (gắn vào AppDomain.CurrentDomain.ProcessExit) và stephbu 's bình luận:

chí này bẫy quá trình có cấu trúc nhất teardowns ví dụ - nhưng tôi không chắc chắn rằng nó sẽ bẫy tất cả những giọt nước mắt. ví dụ. http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx Tái chế quy trình sẽ giết quá trình nếu có vẻ như bị treo - trình xử lý của bạn sẽ không được gọi.

Tôi đề nghị chiến lược sau đây:

Trong xử lý (thường xuyên) ProcessExit (mà chúng tôi cho rằng sẽ không được gọi vào một tái chế hồ bơi ứng dụng), viết một số tập tin vào đĩa như "app_domain_end_ok.tmp".

Sau đó, trong Application_Start của kiểm tra global.asax cho tệp này. Nếu nó không tồn tại nó là một dấu hiệu cho thấy các ứng dụng không được chấm dứt một cách sạch sẽ (hoặc đó là lần đầu tiên nó bắt đầu). Đừng quên xóa tệp này khỏi đĩa sau khi kiểm tra.

Tôi không tự mình thử, nhưng có thể đáng để thử.

+0

Cảm ơn @splattne vì tín dụng ... – stephbu

+0

Tôi đã không xác nhận điều này nhưng tôi nghi ngờ rằng quá trình tái chế có hai chiến lược - 1) tín hiệu chấm dứt quá trình và chờ trong khi bỏ phiếu cho quá trình thoát - nó sẽ kích hoạt ProcessExit trong điều kiện bình thường. 2) Khi hết thời gian chờ, hãy chờ PID. – stephbu

1

Tôi chưa bao giờ cố gắng này bản thân mình, nhưng bạn có thể thử để đính kèm một event handler cho sự kiện ProcessExit của AppDomain.

... 
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit); 
... 

void OnExit(object sender, EventArgs e) { 
    // do something 
} 

Tôi hy vọng điều này sẽ hữu ích!

+0

Điều này sẽ bẫy các quy trình xử lý có cấu trúc nhất, ví dụ: - nhưng tôi không chắc rằng nó sẽ bẫy tất cả những giọt nước mắt. ví dụ: http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx Quá trình tái chế sẽ giết quá trình nếu nó có vẻ bị treo - trình xử lý của bạn sẽ không được gọi. – stephbu

6

tôi tìm thấy bài viết này trên Scott Guthries blog:

Logging ASP.NET Application Shutdown Events

người trên một listserv gần đây đã hỏi liệu có một cách để tìm ra tại sao và khi khởi động lại ASP.NET miền ứng dụng. Cụ thể, ông đang tìm kiếm nguyên nhân chính xác của những gì đã kích hoạt chúng trên ứng dụng của mình trong một sản phẩm được chia sẻ môi trường được lưu trữ (đó là một sự thay đổi của tập tin web.config). thay đổi xóa thư mục, số lượng tối đa-compilations đạt hạn ngạch, \ thay đổi thư mục bin, v.v ...).

Thomas trong nhóm của tôi có một đoạn mã mát mẻ mà anh ấy viết sử dụng một số thủ thuật phản chiếu riêng tư tiện lợi để chụp và ghi lại thông tin này. Việc sử dụng lại và thêm vào bất kỳ ứng dụng nào cũng có thể được sử dụng để ghi lại thông tin ở bất cứ nơi nào bạn muốn. gửi nó đến cơ sở dữ liệu hoặc qua một email tới quản trị viên). Mã hoạt động với cả ASP.NET V1.1 và ASP.NET V2.0.

Chỉ cần thêm System.Reflection và System.Diagnostics namespace để bạn Global.asax lớp/tập tin, và sau đó thêm sự kiện Application_End với mã này:

public void Application_End() { 

    HttpRuntime runtime = 
     (HttpRuntime) typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", 
      BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, 
      null, null, null); 

    if (runtime == null) 
     return; 

    string shutDownMessage = 
     (string) runtime.GetType().InvokeMember("_shutDownMessage", 
      BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, 
      null, runtime, null); 

    string shutDownStack = 
     (string) runtime.GetType().InvokeMember("_shutDownStack", 
      BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, 
      null, runtime, null); 

    if (!EventLog.SourceExists(".NET Runtime")) { 
     EventLog.CreateEventSource(".NET Runtime", "Application"); 
    } 

    EventLog log = new EventLog(); 
    log.Source = ".NET Runtime"; 

    log.WriteEntry(String.Format(
      "\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}", 
      shutDownMessage, shutDownStack), 
     EventLogEntryType.Error); 
} 
0

tôi đã được nhiều thành công hơn với việc gắn vào sự kiện DomainUnload, nó được kích hoạt trên AppPool tái chế và ngừng hoạt động của AppPool.

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;

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