【问题标题】:Start WCF service in a new AppDomain to enable shadow copy (Windows Service hosted)在新的 AppDomain 中启动 WCF 服务以启用卷影复制(Windows 服务托管)
【发布时间】:2014-08-16 03:13:35
【问题描述】:

我有一个 WCF 服务库 (MyWCFService),它使用 MEF 加载插件并由 Windows 服务托管(所有 .NET 4.0)。我现在尝试在新的AppDomain 中运行它并启用ShadowCopyFiles,希望我可以在运行时更新插件。这是 Windows 服务项目中的代码。

程序.cs

 static class Program
    {  
        static void Main()
        {  
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
               new MyService() 
            };
            ServiceBase.Run(ServicesToRun);
        }
    }

MyService.cs

  public partial class MyService: ServiceBase
    {
        internal static ServiceHost MyServiceHost = null;
        public MyService()
        {
             // this works but is deprecated..
             AppDomain.CurrentDomain.SetShadowCopyFiles();

            //this is not working.. DLLs still get locked. Require for a new AppDomain
            //AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true";  

            InitializeComponent();
        }   

        protected override void OnStart(string[] args)
        {
            if(MyServiceHost  !=null)
            {
                MyServiceHost.Close();
            }
            try
            {
                MyServiceHost= new ServiceHost(typeof(MyWCFService));         
                MyServiceHost.Open();
            }
            catch(Exception)
            {
            }          
        }

        protected override void OnStop()
        {
            if (MyServiceHost!= null)
            {
                MyServiceHost.Close();
                MyServiceHost= null;
            }
        }       
    }

有什么办法吗?我已经做了很多搜索,但仍然不知道如何使它与我当前的设置一起工作(或者我只是无法理解......)

我尝试在Main() 内创建一个新的AppDomain 并使用 domain.DoCallBack(new CrossAppDomainDelegate(() => { ServiceBase.Run(ServicesToRun); })) 启动服务,但我无法启动它并不断收到"Error 1053: The service did not respond to the start or control request in a timely fashion"

然后我尝试通过在MyWCFService.cs 中设置AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true"; 来为当前应用域启用卷影复制,就在InitializeComponent(); 之前我可以启动服务,但 dll 仍然被锁定。但是,如果我使用AppDomain.CurrentDomain.SetShadowCopyFiles();(一种已弃用的方法)启用卷影副本,一切正常。我更糊涂了。

【问题讨论】:

    标签: c# wcf windows-services appdomain shadow-copy


    【解决方案1】:

    好的,我最终创建了一个继承自 MarshalByRefObject 的 shell/proxy 类并从那里启动服务,代码如下:

    ServiceShell.cs

    public class ServiceShell:MarshalByRefObject
    {
         internal static ServiceHost MyServiceHost = null;
    
         public void Run()
         {
             if (MyServiceHost != null)
             {
                 MyServiceHost.Close();
             }
             try
             {
                 MyServiceHost = new ServiceHost(typeof(MyWCFService));
                 MyServiceHost.Open();
             }
             catch (Exception)
             {
             }          
         }
    
         public void Stop()
         {
             if (MyServiceHost!= null)
             {
                 MyServiceHost.Close();
                 MyServiceHost = null;
             }
         }
    }
    

    MyService.cs

    public partial class MyService: ServiceBase
    {        
        AppDomain domain;
        ServiceShell runner;
    
        public MyService()
        {   
            var setup = new AppDomainSetup
            {
                ShadowCopyFiles = "true"
            };
            domain = AppDomain.CreateDomain("MyServiceHostDomain", AppDomain.CurrentDomain.Evidence, setup);
    
            runner = (ServiceShell)domain.CreateInstanceAndUnwrap
                (typeof(ServiceShell).Assembly.FullName, typeof(ServiceShell).FullName);
            InitializeComponent();
    
        }
    
        protected override void OnStart(string[] args)
        {          
            runner.Run();
        }
    
        protected override void OnStop()
        {
            runner.Stop();
            AppDomain.Unload(domain);
        }       
    }
    

    【讨论】:

    • 我正在使用确切的模式,但在Unload 上得到ThreadAbortException。此外,Thread.ResetAbort() 什么都不做,所以整个事情都崩溃了。
    • @itsho,我认为这是预期的结果:使用 Abort 方法终止域中的线程,该方法在线程中抛出 ThreadAbortException。 AppDomain.Unload Method跨度>
    猜你喜欢
    • 2011-06-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 2011-07-04
    • 2010-12-28
    • 1970-01-01
    相关资源
    最近更新 更多