2015-06-01 13 views
5

Tất cả các bài viết trên Internet nói rằng việc sử dụng Thread.Abort là điều xấu (vì các nguyên tắc đồng bộ hóa thuộc về hệ điều hành và quá trình không chấm dứt, và nguyên thủy có thể vẫn bị khóa sau khi hủy bỏ chuỗi). Các nhà phát triển khuyên nên chấm dứt toàn bộ quy trình thay vì, bởi vì hệ điều hành sẽ tự do đồng bộ hóa nguyên thủy khi quá trình dừng lại.Các lớp đồng bộ hóa mỏng cho mỗi AppDomain hoặc cho mỗi Process?

  1. AppDomain trợ giúp dỡ hàng, Nếu ai sẽ sử dụng Slim nguyên gốc đồng bộ hóa? (Với .net 4.0 một số lớp mới đã được thêm vào liên quan đến luồng: ManualResetEventSlim, SemaphoreSlim, ReaderWriterLockSlim).

    Tài liệu nói rằng những nguyên thủy này không thể được sử dụng cho các quy trình khác nhau, vì mã thực thi nguyên thủy được quản lý hoàn toàn. Nhưng tôi không hiểu - những nguyên thủy này có hoạt động thông qua biên giới AppDomain hay không. (xem Can't set synchronization context when using appdomains)

  2. Nếu có, họ làm như thế nào? Nếu không, thì tại sao tài liệu bỏ qua giới hạn này?

UPD: Tất cả mã của tôi đều được tôi tin cậy, bao gồm mã bên trong tên miền mà tôi tải. Tôi không muốn rời khỏi chuỗi hoạt động, khi đến lúc chấm dứt nó. Tôi muốn chấm dứt (hủy bỏ) chủ đề thay vì "thiết lập cờ" và "làm cho kiến ​​trúc đẹp". Nếu nó là cần thiết để tạo thêm thread đầu tiên (tôi nghĩ rằng điều này là cần thiết lúc bắt đầu xử lý nền trong tên miền riêng biệt để tạo thêm một sợi), tôi sẽ làm. Tôi không muốn sử dụng "thiết lập cờ" phương pháp tiếp cận, bởi vì nó đòi hỏi tôi để thuật toán nền cụ với cờ kiểm tra, tôi không nên, đó là thời gian chạy hoặc trình biên dịch nên tự động hóa thiết bị cho tôi. Ngay bây giờ không có công cụ như vậy, đó là lý do tại sao tôi đang cố gắng áp dụng cách tiếp cận với việc dỡ miền.

Thêm kiểm tra giữa mỗi lệnh (hoặc trong chu kỳ lồng nhau sâu) sẽ làm chậm mã đáng kể. Việc thêm séc vào các vị trí ngẫu nhiên sẽ không đảm bảo việc chấm dứt nhanh chóng. Nếu khó khăn trong việc viết mã an toàn có thể được giải quyết, tại sao không cố gắng hủy bỏ các chủ đề và dỡ bỏ tên miền?

+1

Bạn sẽ nhận được chúng thông qua ranh giới AppDomain như thế nào? Chúng không được tuần tự hóa, cũng như chúng không kế thừa từ 'MarshalByRefObject'. –

+2

AppDomain giải quyết vấn đề này. Nhưng việc sử dụng đồng bộ hóa nguyên gốc trên các miền ứng dụng không thể hoạt động, bạn phải có khả năng vứt bỏ mọi thứ *. –

+0

Có nhiều vấn đề hơn với 'Thread.Abort' hơn những gì bạn đã đề cập (trên thực tế, một số nguyên thủy đồng bộ hóa được phát hành tốt với' Thread.Abort'; với điều kiện là thread thực sự chết). Câu hỏi là, tại sao bạn đang cố gắng sử dụng phá thai tích cực thay vì hủy hợp tác? Chỉ cần gửi tín hiệu và để chủ đề quyết định khi nào an toàn để hủy. Viết mã abort-an toàn là khó khăn hơn nhiều so với mã chỉ an toàn chỉ - cho cả tài nguyên được quản lý và nguồn gốc. – Luaan

Trả lời

2

Bạn hiểu sai các AppDomain, ProcessThread định nghĩa - AppDomains always lives in one process, but one process can be a master for different AppDomains *:

Khả năng chạy nhiều ứng dụng trong một quá trình duy nhất tăng đáng kể khả năng mở rộng máy chủ.

  • điều này tương tự cho Thread, chỉ đề cập đến.

Vì vậy, câu trả lời cho câu hỏi của bạn là , các slim synchronization primitives sẽ làm việc với nhiều AppDomains, như không có cuộc gọi qua quá trình trong kiến ​​trúc như vậy, chỉ có một sự phân biệt hợp lý cho các quy trình khác nhau.

Đối với các câu hỏi liên quan, không có vấn đề với nguyên thủy đồng bộ ở đó, chỉ với SynchronizationContext, đó là Thread cụ thể, nhưng không AppDomain cụ thể.

Bạn có thể tìm một câu trả lời tuyệt vời về sự khác biệt giữa AppDomain, ThreadProcess đây: Difference between AppDomain, Assembly, Process, and a Thread

Đối với dỡ AppDomain, tôi nghĩ rằng bạn có thể cấu trúc mã của bạn như bạn có thể bắt đầu một công nhân Thread vào của bạn AppDomain ít tiếp cận với các nguồn tài nguyên hệ thống, và chỉ cần chờ đợi cho nó được hoàn thành, một cái gì đó giống như it mentioned here:

using System; 
using System.Threading; 
using System.Threading.Tasks; 

class Program 
{ 
    static void Main() 
    { 
     var ad = AppDomain.CreateDomain("WhereTheWorkHappens"); 

     Task<string> t = DoWorkInOtherDomain(ad); 
     Console.WriteLine("waiting..."); 
     Console.WriteLine(t.Result); 

     Console.ReadLine(); 
    } 

    static Task<string> DoWorkInOtherDomain(AppDomain ad) 
    { 
     var ch = new MarshaledResultSetter<string>(); 

     Worker worker = (Worker)ad.CreateInstanceAndUnwrap(typeof(Worker).Assembly.FullName, typeof(Worker).FullName); 
     worker.DoWork(ch); 

     return ch.Task; 
    } 

    class Worker : MarshalByRefObject 
    { 
     public void DoWork(MarshaledResultSetter<string> callback) 
     { 
      ThreadPool.QueueUserWorkItem(delegate 
      { 
       Thread.SpinWait(500000000); 
       callback.SetResult(AppDomain.CurrentDomain.FriendlyName); 
      }); 
     } 
    } 

    class MarshaledResultSetter<T> : MarshalByRefObject 
    { 
     private TaskCompletionSource<T> m_tcs = new TaskCompletionSource<T>(); 
     public void SetResult(T result) { m_tcs.SetResult(result); } 
     public Task<T> Task { get { return m_tcs.Task; } } 
    } 
} 

là một ý tưởng bổ sung cho bạn, bạn có thể đọc về Sandboxing your code with TPL, theo tôi nghĩ, là cách tiếp cận tốt hơn vì bạn không quản lý tài nguyên hệ thống theo cách thủ công và ít có cơ hội bị tấn công bởi mã không đáng tin cậy của bạn.

Ngoài ra, bạn có thể tìm thấy dự án GitHub với Cross-AppDomain Marshaling friendly TPL wrappers for APM

+0

Tôi hiểu, rằng AppDomain thuộc về chỉ một quá trình và AppDomain không span một số quy trình. Tôi hiểu rằng SynchronizationContext (cho ContextBoundObjects) không span một số AppDomains. Tại sao bạn quyết định, tôi không? Có vẻ như bạn đang chiến đấu với những hiểu lầm cũ của riêng mình, giả sử rằng tôi cũng vậy. Của tôi là khác nhau! Tôi không hiểu, làm thế nào để syncronize giữa AppDomains (không sử dụng nguyên gốc đồng bộ hóa cấp hệ điều hành). Tôi vẫn không hiểu những gì xảy ra với thread khi nó vượt qua ranh giới AppDomain. – R2D4

+0

Nhìn vào câu hỏi này - http://stackoverflow.com/questions/21493944/synchronizing-between-appdomains-using-named-mutex Tôi nghĩ rằng câu hỏi được diễn đạt không chính xác. Chúng tôi đồng bộ hóa Chủ đề, không phải của AppDomain. Nhưng Chủ đề thuộc về Processes, không phải cho AppDomains. – R2D4

+0

Tôi đã trả lời câu hỏi của bạn: Có, phiên bản mỏng sẽ hoạt động trên nhiều 'AppDomain' miễn là' Chủ đề' khác nhau khi chúng vẫn ở trong cùng một 'Process' **. – VMAtm

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