C# 在新AppDomain中启动WCF服务以启用卷影复制(Windows服务托管)
我有一个WCF服务库(C# 在新AppDomain中启动WCF服务以启用卷影复制(Windows服务托管),c#,wcf,windows-services,appdomain,shadow-copy,C#,Wcf,Windows Services,Appdomain,Shadow Copy,我有一个WCF服务库(MyWCFService),它使用MEF加载插件,并由Windows服务(所有.NET 4.0)托管。我现在尝试在一个新的AppDomain中运行它,并启用ShadowCopyFiles,希望能在运行时更新插件。下面是Windows服务项目中的代码 Program.cs static class Program { static void Main() { ServiceBase[] Services
MyWCFService
),它使用MEF
加载插件,并由Windows服务(所有.NET 4.0)托管。我现在尝试在一个新的AppDomain
中运行它,并启用ShadowCopyFiles
,希望能在运行时更新插件。下面是Windows服务项目中的代码
Program.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;
}
}
}
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);
}
}
有什么办法吗?我已经做了很多搜索,但仍然不知道如何使用我的当前设置(或者我就是不明白…)
我尝试在Main()内创建一个新的AppDomain
,并使用
domain.DoCallBack(新的CrossAppDomainDelegate(()=>{ServiceBase.Run(ServicesToRun);}))
启动该服务,但我无法启动它并不断收到“错误1053:该服务未及时响应启动或控制请求”
然后我试图通过设置appdomain.CurrentDomain.SetupInformation.ShadowCopyFiles=“true”来启用当前appdomain的卷影复制代码>在MyWCFService.cs
的初始化组件()之前代码>我可以启动服务,但DLL仍处于锁定状态。但是,如果我使用AppDomain.CurrentDomain.SetShadowCopyFiles()
(一种不推荐使用的方法)要启用卷影复制,一切正常。我更困惑了。好的,我最终创建了一个继承自的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
{
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;
}
}
}
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);
}
}
我使用的是完全相同的模式,但是在卸载上获得线程异常。此外,Thread.ResetAbort()
,什么也不做,所以整个过程都崩溃了。@itsho,我认为这是预期的结果:域中的线程使用Abort方法终止,该方法在线程中抛出ThreadAbortException。