ServiceControler.GetServices()默默地在后台线程中躲避

时间:2013-11-05 16:05:29

标签: c# multithreading

我正在运行以下行来获取给定计算机的所有服务的列表:

ServiceController[] services = ServiceController.GetServices(compName);

如果我在主线程上运行此命令并传入一个存在的计算机名称,但我没有权限查看其中的服务,例如:

ServiceController.GetServices("OtherComp"); 
  

InvalidOperationException异常:
  无法在计算机'OtherComp'上打开服务控制管理器。此操作可能需要其他权限。

我完全相信这会发生。但是我的问题是在后台线程上运行它。采用这个完全完整的控制台程序:

using System.ComponentModel;
using System.ServiceProcess;

namespace ServiceTesting
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            ServiceAccessor sa = new ServiceAccessor();
            sa.Run();
        }
    }

    public class ServiceAccessor
    {
        BackgroundWorker bw;

        public ServiceAccessor()
        {
            bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new
                RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }

        public void Run()
        {
            bw.RunWorkerAsync();
        }

        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            //this line is where the bail happens
            var services = ServiceController.GetServices("OtherComputer");
        }

        void bw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
        {
            // the code will never get to this method
            if (e.Error != null)
            {
                //something
            }
        }
    }
}

我希望抛出一个异常,但是一旦代码尝试执行这一行,它就会脱离线程。

我无法将该行包裹在try\catch中;它不会抓住它。这可能与asp.net的ThreadAbort问题相似(但这只是猜测)。

msdn page on the ServiceController Class表示静态函数是线程安全的,但function's msdn page上的评论者说它不是。

1 个答案:

答案 0 :(得分:1)

BackgroundWorker在内部捕获异常,您可以通过RunWorkerCompleted事件查看它:

private void backgroundWorker1_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e)
{
    // First, handle the case where an exception was thrown. 
    if (e.Error != null)
    {
        // deal with error
    }
}

http://msdn.microsoft.com/en-us/library/system.componentmodel.runworkercompletedeventargs.aspx

UPD:但是,它与Thread类一样正常工作:

new Thread(() =>
    {
        try
        {
            var services = ServiceController.GetServices("OtherComputer");
        }
        catch
        {
        }
    }).Start();