- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在努力让 Windows 服务在有新版本时自动重启应用程序。我的代码在下面,它确实有效。我的问题是:这里某处有很大的禁忌吗?我不熟悉在单独的线程上创建应用程序域,我想知道是否有更优雅的方法来完成此操作。我还担心我在处理这件事上可能有很大的盲点。任何建议表示赞赏。
有两个常规部分:运行的 Windows 服务,在不同的进程中启动我的应用程序,然后轮询以检测该应用程序的新版本何时可用。第二部分是启动、更新、重启的实际应用。
首先,当服务启动时,它会调用 LoadApp() 以便应用程序开始运行。
private void LoadApp()
{
// ** appDomainSetup here **
this._appDomain = AppDomain.CreateDomain("MyUpdatedApp", AppDomain.CurrentDomain.Evidence, appDomainSetup);
this._tokenSource = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
try
{
this._appDomain.ExecuteAssembly(assembly);
}
catch (AppDomainUnloadedException ex)
{
Debug.WriteLine(ex.ToString());
}
}, _tokenSource.Token);
}
然后,每隔 10 秒,计时器调用此方法:
private void Process(object stateInfo)
{
if (!Monitor.TryEnter(_locker)) { return; }
try
{
// Check for new binaries. If new, copy the files and restart the app domain.
if (!NewAppVersionReady()) { return; }
DeleteFiles();
CopyFiles();
RestartAppDomain();
}
finally
{
Monitor.Exit(_locker);
}
}
RestartAppDomain() 看起来像这样。请注意,当我在此方法的第二行卸载应用程序域时出现异常。 (我通过捕获异常并基本上忽略它来解决这个问题。)
private void RestartAppDomain()
{
this._tokenSource.Cancel();
AppDomain.Unload(this._appDomain);
LoadApp();
}
编辑:我后来发现 AppDomain.Unload() 行是不必要的。没有它,该服务仍会使用新版本更新应用程序,然后启动新版本的应用程序。我最关心的是在 token 源上调用 Cancel()。我希望应用能够正常关闭,而不是强制关闭。
最佳答案
通过反复试验和学习,我似乎已经确定了一个不错的解决方案。我想我会把它贴在这里以防它对其他人有帮助。
首先,我在一个单独的项目中创建了一个接口(interface),因此 self 更新的应用程序不必引用实际在其自己的应用程序域中运行的应用程序。使用此接口(interface),以便 self 更新的应用程序可以调用其他应用程序上的启动和停止。
public interface IStartStop
{
void Start();
void Stop();
}
在单独域中运行的应用程序中,我让类从 MarshalByRefObject 派生,并实现 IStartStop。
public class PrestoTaskRunnerController : MarshalByRefObject, IStartStop, IDisposable
这允许我从我的 self 更新应用程序启动和停止这个应用程序:
this._appDomain = AppDomain.CreateDomain(this._appName, AppDomain.CurrentDomain.Evidence, appDomainSetup);
this._startStopControllerToRun = (IStartStop)this._appDomain.CreateInstanceFromAndUnwrap(assemblyName, this._fullyQualifiedClassName);
this._startStopControllerToRun.Start();
停止它是这样完成的:
this._startStopControllerToRun.Stop();
AppDomain.Unload(this._appDomain);
还有一些细节,但这是一般概念,而且似乎运作良好。
关于c#-4.0 - 在不同线程上使用应用程序域 self 更新应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8538659/
我是一名优秀的程序员,十分优秀!