2012-06-18 37 views
14

Tôi có thể xác định nhân viên nền trong một phương pháp không?Nhân viên nền và thu gom rác thải?

private void DownLoadFile(string fileLocation){ 
    BackgroundWorker worker = new BackgroundWorker(); 

    worker.DoWork += new DoWorkEventHandler((obj, args) => { 
     // Will be executed by back ground thread asynchronously. 
     args.Result = Download(fileLocation); 
    }); 

    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, args) => { 
     // will be executed in the main thread. 
     Result r = args.Result as Result; 
     ReportResult(r); 
    }); 

    worker.RunWorkerAsync(fileLocation); 
} 

Câu hỏi: Nếu Tải về() chức năng mất nhiều thời gian để tải về các tập tin, GC có thể kick vào và thu thập đối tượng người lao động trước khi RunWorkerCompleted() được thực thi?

+0

Tôi khuyên bạn nên sử dụng đại biểu (Hành động (Chuỗi) sẽ thực hiện) và sau đó gọi BeginInvoke. Tôi không thấy bất kỳ nhu cầu nào cho BackgroundWorker trong mã này. Bạn vẫn có thể đính kèm một sự kiện khi phương thức được thực hiện. – JDB

+1

Cách tốt hơn để thực hiện việc này là thêm nó vào hàng đợi của luồng chủ đề bằng cách sử dụng 'QueueUserWorkItem': http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx –

+0

@J ... Các threadpool là tốt đẹp, nhưng nó làm cho việc xử lý gọi lại * trên bên phải SynchronizationContext * khó khăn hơn. TPL xử lý độc đáo, mặc dù. –

Trả lời

12

Cho rằng bạn không thực sự sử dụng hầu hết các chức năng của BackgroundWorker, tôi sẽ khuyên bạn sử dụng các TPL cho thay này:

private void DownLoadFile(string fileLocation) 
{ 
    Task.Factory.StartNew(() => Download(fileLocation)) 
     .ContinueWith(t => ReportResult(t.Result), TaskScheduler.FromCurrentSynchronizationContext()); 
} 

đó được cho biết, đối tượng worker sẽ không rác được thu thập khi nó đang chạy, vì luồng ThreadPool sẽ giữ nhân viên làm "đối tượng được sử dụng". Bộ thu gom rác sẽ không thể thu thập nó cho đến sau khi trình xử lý sự kiện hoàn thành thực thi, tại thời điểm đó sẽ không có mã người dùng nào có thể đạt được phiên bản BackgroundWorker.

Ngoài ra, nó có khả năng giữ cho thể hiện của lớp này không bị thu gom rác, như các phương pháp thể hiện (ReportResults) được sử dụng bởi việc đóng giữ cho trường hợp "này" có thể truy cập và không đủ điều kiện cho GC.

+0

Đây không thực sự là câu trả lời cho câu hỏi của OP. Vẫn còn lời khuyên tốt. – JDB

+1

@ Cyborgx37 Đã thêm câu trả lời trực tiếp cho câu hỏi của OP. –

+0

Có thực sự là một ý tưởng hay để cho một biến số như vậy đi ra khỏi phạm vi, mặc dù? Các lập trình viên đến sau khi anh ta sẽ mong đợi để xem một biến trong phạm vi đang được tham chiếu, không phải một số biến zombie đó ra khỏi đó trong ether ở đâu đó. –

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