在等待WMI通知事件时取消BackgroundWorker

时间:2015-07-20 22:03:16

标签: c# .net multithreading wmi backgroundworker

我有BackgroundWorker监视要触发的WMI通知事件。我的查询类似于SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name=proccessnamehere。此查询轮询每2秒符合WHERE条件的__InstanceDeletionEvent。有时我正在观看的过程需要一段时间,将事件延迟解雇,我想取消它。我读到的关于取消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();
    }

1 个答案:

答案 0 :(得分:0)

您不能立即强制终止后台工作人员(不使用取消挂起标志),它不是以这种方式设计的。

Task Parallel Library提供了该功能。

如果您真的想使用BackgroundWorker并实现以下目标,则可以选择。可能不是最好的方法..

您可以在DoWork事件中获取运行BackgroundWorker的线程,将其保存在一个字段中,然后您可以中止该线程。

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;
            }