2011-11-29 8 views
6

Tôi có một ứng dụng sử dụng bộ tính giờ để thỉnh thoảng chạy các nhiệm vụ giám sát trên các chuỗi phụ. Một số công việc dọn dẹp này mất rất nhiều thời gian và tôi muốn có thể hủy bỏ các tác vụ này (một cách duyên dáng nếu có thể) khi người dùng của tôi kết thúc chương trình.Tôi có thể dừng một System.Threading.Timer

Có cách nào để hủy bỏ chuỗi theo chương trình như tôi có thể với Thread.Abort() hay tôi phải thêm cờ vào mã để chỉ ra rằng chuỗi đã hoàn tất và kiểm tra xem ở vị trí phù hợp trong mã được bắt đầu bởi bộ đếm thời gian?

+0

Sẽ không chấm dứt ứng dụng chấm dứt tất cả các chủ đề? – CJ7

Trả lời

4

Không có cách nào để biết số Thread mà cuộc gọi lại Threading.Timer sẽ chạy trước thời hạn. Do đó không có cách chung để hủy bỏ nó. Có thể tự gọi lại giao tiếp với cá thể Thread nhưng nó mở ra một vài điều kiện chủng tộc

Lưu ý: Nói chung, sử dụng Abort là hành vi không tốt. Đó là một cách khá đáng tin cậy để kết thúc với khó khăn để phát hiện deadlocks và/hoặc rò rỉ tài nguyên. Bạn nên sử dụng cơ chế thụ động như CancellationToken

+0

Một lần nữa, +1 trên bệnh hủy bỏ. –

5

Bạn có thể ngừng bộ hẹn giờ trước khi gọi lại thực thi bằng cách sử dụng .change, nhưng sau khi bắt đầu thực thi, bạn nên sử dụng cờ cấp ứng dụng để cho phép mã của bạn thoát.

Như một lưu ý phụ, bạn không nên sử dụng thread.abort() trừ khi bạn hoàn toàn chắc chắn 100% rằng bạn biết trạng thái của nó sẽ bị bỏ lại. Nó có thể làm mất ổn định nghiêm trọng ứng dụng của bạn theo những cách kỳ lạ.

+0

+1 về tránh Thread.Abort() như bệnh dịch hạch ... Họ thậm chí không cho phép Abort() trong TPL. –

1

Bạn có ý nghĩa gì đó trong các dòng này?

using System; 
using System.Threading ; 

class AppCore : IDisposable 
{ 
    Timer TimerInstance ; 
    string[] Args   ; 

    public AppCore(string[] args) 
    { 
     if (args == null) throw new ArgumentNullException("args") ; 
     this.TimerInstance = new Timer(Tick , null , new TimeSpan(0,0,30) , new TimeSpan(0,0,15)) ; 
     this.Args   = args ; 
     this.Cancelled  = false ; 
     this.Disposed  = false ; 
     return ; 
    } 

    public int Run() 
    { 
     // do something useful 
     return 0 ; 
    } 

    private bool Cancelled ; 
    public void Cancel() 
    { 
     lock(TimerInstance) 
     { 
      Cancelled = true ; 
      TimerInstance.Change(System.Threading.Timeout.Infinite , System.Threading.Timeout.Infinite) ; 
     } 
     return ; 
    } 

    private void Tick(object state) 
    { 
     if (!Cancelled) 
     { 
      // do something on each tick 
     } 
     return ; 
    } 

    private bool Disposed ; 
    public void Dispose() 
    { 
     lock (TimerInstance) 
     { 
      if (!Disposed) 
      { 
       using (WaitHandle handle = new EventWaitHandle(false , EventResetMode.ManualReset)) 
       { 
        TimerInstance.Dispose(handle) ; 
        handle.WaitOne() ; 
       } 
       Disposed = true ; 
      } 
     } 
     return ; 
    } 

} 
3

sử dụng this.Timer.Change (Timeout.Infinite, Timeout.Infinite); đầu tiên tôi đã sử dụng phương pháp .dispose nhưng nó không hoạt động trong trường hợp của tôi vì vậy tôi đã sử dụng Timer.change.

đây là giải pháp tốt nhất mà tôi đã tìm thấy.

0
public void stopTimer(){ 
    myThreadingTimer = null; 
} 

Explication: Destroy object = destroy proccess.

+0

Nói chung, câu trả lời hữu ích hơn nhiều nếu chúng bao gồm giải thích về mã được dự định làm gì và tại sao giải quyết vấn đề đó mà không giới thiệu người khác. (Bài đăng này đã được gắn cờ bởi ít nhất một người dùng, có lẽ vì họ nghĩ rằng một câu trả lời không cần giải thích sẽ bị xóa.) –

+0

Explication: Destroy object = destroy proccess. –