void Run() { var cancellationToken = _cancellationTokenSource.Token; _thread = new Thread(() => { var currentRoundStartTime = DateTimeOffset.UtcNow - FloodFrequencyThreshold; while (!cancellationToken.IsCancellationRequested) { var observer = _hostContext.Observer; var lastRoundStartTime = currentRoundStartTime; currentRoundStartTime = DateTimeOffset.UtcNow; var identity = _hostContext.GetNewCellLifeIdentity(_solutionName, _cellName, _deployment); AppDomain domain = AppDomain.CreateDomain("LokadCloudServiceRuntimeCell_" + identity.UniqueCellInstanceName, null, AppDomain.CurrentDomain.SetupInformation); try { try { _entryPoint = (CellAppDomainEntryPoint)domain.CreateInstanceAndUnwrap( Assembly.GetExecutingAssembly().FullName, typeof(CellAppDomainEntryPoint).FullName); } catch (Exception exception) { // Fatal Error observer.TryNotify(() => new CellFatalErrorRestartedEvent(identity, exception)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); continue; } // Forward cancellation token to AppDomain-internal cancellation token source var registration = cancellationToken.Register(_entryPoint.Cancel); var environment = new ApplicationEnvironment(_hostContext, identity, _deployment, _cellDefinition.Assemblies, _sendCommand); try { observer.TryNotify(() => new CellStartedEvent(identity)); _entryPoint.Run(_cellDefinition, _hostContext.DeploymentReader, environment); } catch (ThreadAbortException exception) { Thread.ResetAbort(); observer.TryNotify(() => new CellAbortedEvent(identity, exception)); } catch (Exception exception) { if (cancellationToken.IsCancellationRequested) { observer.TryNotify(() => new CellAbortedEvent(identity, exception)); } else { _entryPoint = null; if ((DateTimeOffset.UtcNow - lastRoundStartTime) < FloodFrequencyThreshold) { observer.TryNotify(() => new CellExceptionRestartedEvent(identity, exception, true)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); } else { observer.TryNotify(() => new CellExceptionRestartedEvent(identity, exception, false)); } } } finally { RemotingServices.Disconnect(environment); _entryPoint = null; observer.TryNotify(() => new CellStoppedEvent(identity)); registration.Dispose(); } } catch (Exception exception) { // Fatal Error observer.TryNotify(() => new CellFatalErrorRestartedEvent(identity, exception)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); continue; } finally { AppDomain.Unload(domain); } } }); _thread.Name = "Lokad.Cloud AppHost Cell (" + _cellName + ")"; _thread.Start(); }