2015-07-20 68 views
0

我有一個BackgroundWorker,它監視要激發的WMI通知事件。我的查詢看起來像SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name=proccessnamehere。此查詢輪詢每隔2秒滿足WHERE條件的__InstanceDeletionEvent。有時我正在看的過程需要一段時間,延遲事件發生,我想取消它。我讀過的關於取消BackgroundWorker的一切建議我使用某種類型的循環。但是,我不確定如何在通知事件中包含循環。有沒有其他方法可以做到這一點?我打得四處計時器,但沒有成功在等待WMI通知事件時取消BackgroundWorker

編輯:代碼示例 - 刪除無關的代碼

(這將執行鍼對遠程計算機)

using System.Management; 
private void backGroundWorkerStart_DoWork(object sender, DoWorkEventArgs e) 
    { 
     object[] args = e.Argument as object[]; 
     string computerName = args[0].ToString(); 
     string processName = args[1].ToString(); 

     ConnectionOptions con = new ConnectionOptions(); 
     con.Impersonation = ImpersonationLevel.Impersonate; 
     con.Authentication = AuthenticationLevel.Default; 
     con.EnablePrivileges = true; 

     ManagementScope scope = new ManagementScope(String.Format(@"\\{0}\ROOT\CIMV2", computerName), con); 

     scope.Connect(); 

     WqlEventQuery query = new WqlEventQuery(String.Format("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='{0}'", processName)); 
     ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query); 

     ManagementBaseObject baseObject = watcher.WaitForNextEvent(); 
    } 
+0

你可以發佈一個(可能是簡化版)你當前的代碼? –

+0

@EricJ。添加了一個簡化的示例希望這是你所要求的。 – HiTech

回答

0

你不能強迫終止立即(不使用取消掛起標誌)的後臺工作人員,它不是那樣設計的。

Task Parallel Library提供了該功能。

如果你真的想使用BackgroundWorker並實現你的目標是一個選項。可能不是最好的辦法..

你可以得到的線程BackgroundWorker運行在DoWork事件保存在一個字段,然後可以中止線程。

private Thread _backgroundWorkerThread; 

public void StartBackgroundWorker() 
{ 
    BackgroundWorker backgroundWorker = new BackgroundWorker(); 
    backgroundWorker.DoWork += DoWork; 
    backgroundWorker.RunWorkerAsync(); 
} 

public void AbortBackgroundWorker() 
{ 
    if(_backgroundWorkerThread != null) 
     _backgroundWorkerThread.Abort(); 
} 

void DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     _backgroundWorkerThread = Thread.CurrentThread; 

     // Do your work... 
    } 
    catch(ThreadAbortException) 
    { 
     // Do your clean up here. 
    } 
} 

參考here更多選項

編輯

可能是你正在尋找的東西像下面。

WqlEventQuery query = new WqlEventQuery(String.Format("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='{0}'", processName)); 
      ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query); 

      ManagementBaseObject baseObject = watcher.WaitForNextEvent(); 

      if (myBackgroundWorkder.CancellationPending) 
      { 
       e.Cancel = true; 
       watcher.Stop(); 
       return 0; 
      } 
+0

每次使用'Thread.Abort'小貓都會死... –

+0

感謝您的回覆。我知道我不能強制終止線程。我知道MSDN上提供的例子,我可以設置一個循環來觀察CancellationPending標誌變爲True,然後設置CancelEventArgs.Canel = True,這應該觸發線程結束。我無法弄清楚如何設置一個循環來檢查CancellationPending標誌的更改。 – HiTech

+0

@HiTech:看看我的更新。可能你正在尋找類似的東西... – CharithJ