2012-07-03 49 views
5

Tôi đang sử dụng System.ComponentModel.BackgroundWorker trong ứng dụng WPF của mình.Thời gian chờ cho BackgroundWorker

Tôi làm cách nào để đặt timeout cho BackgroundWorker?

+1

hết thời gian để làm việc gì? – Dimitri

+1

một cái gì đó, nó làm một cái gì đó, và tôi muốn ngừng làm điều đó sau khi thời gian chờ. –

+0

Đúng như BugFinder đã sử dụng mã thông báo hủy để hủy bỏ việc thực hiện – Dimitri

Trả lời

4

Đề nghị của tôi là sau

backgroundworker1 làm việc - nó chấp nhận hủy bỏ, do đó bạn có thể làm cho nó dừng lại.

backgroundworker2 thực hiện vòng lặp trong khi hết thời gian chờ và khi hết thời gian chờ.

Nếu backgroundworker1 vẫn chạy, các RunWorkerComplete này BackgroundWorker, giết chết tắt backgroundworker1 ..

này cũng nên chấp nhận hủy để nếu backgroundworker1 hoàn thành và đây vẫn chạy , bạn có thể hủy nó.

+0

một chủ đề khác trên thực tế, không dễ dàng, theo cách khác? –

+0

Có lẽ, nhưng để có được thời gian khá chính xác, cũng như chức năng, có nhiều tùy chọn. Bạn có thể làm một số hình thức hậu duệ và liên tục kiểm tra thời gian trôi qua trong công nhân ban đầu của bạn, nhưng, nếu bạn có bất kỳ hình thức chặn cuộc gọi nó cũng có thể vượt quá thời gian chờ. – BugFinder

4

BackgroundWorker không trực tiếp hỗ trợ thời gian chờ, nhưng nó hỗ trợ hủy. Điều này sẽ hoạt động tốt nếu công việc đang được thực hiện là một vòng lặp hoặc cấu trúc khác, nơi bạn có thể định kỳ kiểm tra thành viên hủy bỏ để sau đó hủy bỏ. Bạn sẽ cần một số thứ khác để yêu cầu nhân viên nền hủy sau khi hết giờ. Ở đây tôi đã sử dụng một cuộc gọi không đồng bộ của một hành động.

static void Main(string[] args) 
    { 
     var bg = new BackgroundWorker { WorkerSupportsCancellation = true }; 
     bg.DoWork += LongRunningTask; 

     const int Timeout = 500; 
     Action a =() => 
      { 
       Thread.Sleep(Timeout); 
       bg.CancelAsync(); 
      }; 
     a.BeginInvoke(delegate { }, null); 

     bg.RunWorkerAsync(); 

     Console.ReadKey(); 
    } 

    private static void LongRunningTask(object sender, DoWorkEventArgs eventArgs) 
    { 
     var worker = (BackgroundWorker)sender; 
     foreach (var i in Enumerable.Range(0, 5000)) 
     { 
      if (worker.CancellationPending) 
      { 
       return; 
      } 
      else 
      { 
       //Keep working 
      } 
     } 
    } 

Nếu điều này không thực sự phù hợp với những gì bạn đang cố gắng để hoàn thành bạn có thể quan tâm đến các giải pháp timeout generic tìm thấy tại Implementing a timeout on a function returning a value hoặc Implement C# Generic Timeout. Bạn có thể sử dụng chúng bên trong BackgroundWorker.

+0

Cảm ơn bạn nhưng nó không hoạt động, eventArgs.Cancel không bao giờ trở thành sự thật. –

+0

@ArmenKhachatryan Ồ, tất nhiên là không, tôi đã kiểm tra đối tượng sai để hủy thông tin (^ _ ^;). Tôi đã chỉnh sửa bằng bản sửa lỗi. – vossad01

+0

Làm việc giống như một sự quyến rũ. Rất cảm ơn .... Nếu bạn đang đi chế độ OO ;-), Toàn cầu của bạn có thể var bg = new BackgroundWorker và sử dụng CancelAsync(); bất cứ nơi nào trong mã của bạn. –

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