2010-10-31 31 views
6

Vì vậy, đây là câu chuyện cho đến nay, tôi có thingy công nhân này sử dụng một AppDomain để thực hiện một số nhiệm vụ. Tên miền đắt tiền để thiết lập và rách. Vì vậy, tôi tạo ra một bộ nhớ cache cho mỗi chủ đề của các đối tượng WeakReference cho người lao động thingy như vậy:AppDomain.Unload ném trong Finalizer?

class Worker 
{ 
    [ThreadStatic] 
    static Dictionary<string, WeakReference> _workers; 

    public static Worker Fetch(...) { you get the idea } 

    private AppDomain _domain; 
    public Worker(...) 
    { 
     _domain = AppDomain.Create(...); 
    } 

    ~Worker() 
    { 
     AppDomain.Unload(_domain); 
    } 

    // bla bla bla 
} 

Vấn đề tôi đang gặp là dường như lúc nào cũng ném một ngoại lệ trong các cuộc gọi đến AppDomain.Unload khi GC thu thập:

System.CannotUnloadAppDomainException: Error while unloading appdomain. (Exception from HRESULT: 0x80131015)" 

Vì vậy, tôi nghĩ điều đó thật kinh khủng, tôi biết tôi không có bất cứ điều gì 'đang chạy' trong tên miền đó ... Whats thỏa thuận? Một chút đào và thử và sai tôi đến với điều này:

~Worker() 
    { 
     new Action<AppDomain>(AppDomain.Unload) 
      .BeginInvoke(_domain, null, null); 
    } 

Vì vậy, câu hỏi của tôi là:

  1. Will AppDomain.Unload luôn luôn thất bại từ một finalizer? Tại sao?
  2. Tôi có phải trải nghiệm bất cứ điều gì 'không mong muốn' với cách giải quyết ở trên không?
+0

Có thể trùng lặp của [Tại sao lỗi AppDomain.Unload() trong finalizer?] (Https://stackoverflow.com/questions/1891480/why-does-appdomain-unload-error-in-finalizer) – Fabian

Trả lời

10

Tên miền ứng dụng được tải bởi một chuỗi CLR riêng biệt. Chủ đề đó không thể chạy trong khi chuỗi finalizer đang chạy. Bạn đang nhận được ngoại lệ vì CLR thông báo rằng chuỗi tải không thực hiện tiến trình. Nó không bao giờ được đi bởi vì thread finalizer bị chặn trên cuộc gọi Unload.

Bế tắc.

Giải pháp thay thế của bạn thực sự giải quyết bế tắc đó. Việc dỡ hàng một cách rõ ràng thay vì dựa vào trình hoàn thiện là cách tiếp cận tốt hơn ở đây.

+0

Ahh, as Tôi nghi ngờ. Đồng ý rằng dỡ hàng rõ ràng sẽ tốt hơn; Tuy nhiên, tôi không có một nơi mà từ đó tôi có thể dỡ bỏ các tên miền được lưu trữ. Đó là lý do cho WeakReference. –

+0

Chúng tôi vừa bắt đầu nhận được nó sau khi nâng cấp dự án lên .NET 4. 3.5 SP1 dường như không có hành vi này đối với chúng tôi. Tôi có thể hiểu được logic trong câu trả lời này mặc dù rất vui khi sửa mã bị hỏng của chúng tôi. – nbevans

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