public async Task TestSuspend() { var collection = new ModuleCollection(); var modules = new SuspensionAwareModule[] { new SuspensionAwareModule(true), new SuspensionAwareModule(true), new SuspensionAwareModule(true), new SuspensionAwareModule(true), }; foreach (var m in modules) { var lt = m.QueryView <IModuleLifetime>(); Assert.IsNotNull(lt, "Модуль должен поддерживать управление временем жизни"); Assert.IsTrue(lt.IsSuspendAware, "Модуль должен поддерживать приостановку работы"); } foreach (var m in modules) { collection.RegisterModule <SuspensionAwareModule, ISuspensionAwareModule>(m); } await collection.Seal(); foreach (var m in modules) { Assert.IsFalse(m.IsSuspended, "Модуль не должен быть приостановлен"); } await collection.Suspend(); foreach (var m in modules) { Assert.IsTrue(m.IsSuspended, "Модуль должен быть приостановлен"); } await collection.Resume(); foreach (var m in modules) { Assert.IsFalse(m.IsSuspended, "Модуль не должен быть приостановлен после Resume"); Assert.IsTrue(m.IsAllResumed, "Должен быть вызван метод AllResumed()"); Assert.AreEqual(1, m.AllResumedCount, "Метод AllResumed() должен быть вызван один раз"); } await collection.Dispose(); }
public async Task TestAttachedLifetime() { var collection = new ModuleCollection(); await collection.Seal(); var provider = collection.GetModuleProvider(); var modules = new SuspensionAwareModule[] { new SuspensionAwareModule(true, true), new SuspensionAwareModule(true, true), new SuspensionAwareModule(true, true), new SuspensionAwareModule(true, true), }; var suspendTasks = new List <Task>(); var resumeTasks = new List <Task>(); var disposeTasks = new List <Task>(); foreach (var m in modules) { var lt = m.QueryView <IModuleLifetime>(); var lte = m.QueryView <IModuleLifetimeEvents>(); Assert.IsNotNull(lt, "Модуль должен поддерживать управление временем жизни"); Assert.IsNotNull(lte, "Модуль должен поддерживать события времени жизни"); await lt.InitializeModule(provider); var tcsd = new TaskCompletionSource <bool>(); var tcss = new TaskCompletionSource <bool>(); var tcsr = new TaskCompletionSource <bool>(); var tcsar = new TaskCompletionSource <bool>(); lte.Disposed += _ => { tcsd.SetResult(true); }; lte.Suspended += _ => { tcss.SetResult(true); }; lte.Resumed += _ => { tcsr.SetResult(true); }; lte.AllResumed += _ => { tcsar.SetResult(true); }; disposeTasks.Add(tcsd.Task); suspendTasks.Add(tcss.Task); resumeTasks.Add(tcsr.Task); resumeTasks.Add(tcsar.Task); } foreach (var m in modules) { var lt = m.QueryView <IModuleLifetime>(); await lt.AllModulesInitialized(); } foreach (var m in modules) { Assert.IsFalse(m.IsSuspended, "Модуль не должен быть приостановлен"); } await collection.Suspend(); var suspendWaiter = new Task[] { Task.WhenAll(suspendTasks.ToArray()), Task.Delay(TimeSpan.FromSeconds(10)) }; var suspendResult = await Task.WhenAny(suspendWaiter); Assert.AreSame(suspendWaiter[0], suspendResult, "Сработал таймаут по событию Suspended"); foreach (var m in modules) { Assert.IsTrue(m.IsSuspended, "Модуль должен быть приостановлен"); } await collection.Resume(); var resumeWaiter = new Task[] { Task.WhenAll(resumeTasks.ToArray()), Task.Delay(TimeSpan.FromSeconds(10)) }; var resumeResult = await Task.WhenAny(resumeWaiter); Assert.AreSame(resumeWaiter[0], resumeResult, "Сработал таймаут по событию Resumed"); foreach (var m in modules) { Assert.IsFalse(m.IsSuspended, "Модуль не должен быть приостановлен после Resume"); Assert.IsTrue(m.IsAllResumed, "Должен быть вызван метод AllResumed()"); Assert.AreEqual(1, m.AllResumedCount, "Метод AllResumed() должен быть вызван один раз"); } await collection.Dispose(); var disposeWaiter = new Task[] { Task.WhenAll(disposeTasks.ToArray()), Task.Delay(TimeSpan.FromSeconds(10)) }; var disposeResult = await Task.WhenAny(disposeWaiter); Assert.AreSame(disposeWaiter[0], disposeResult, "Сработал таймаут по событию Disposed"); foreach (var m in modules) { Assert.IsTrue(m.IsDisposed, "Модуль должен быть завершён"); } }
public async Task BoardReferenceParallelQuery() { var boards = await TestResources.LoadBoardReferencesFromResource(); var parser = _provider.FindNetworkDtoParser <MobileBoardInfoCollection, IList <IBoardReference> >(); var result = parser.Parse(boards); await _store.UpdateReferences(result, true); async Task <Nothing> Query(int cid, int qid) { Logger.LogMessage($"Query {cid}:{qid} started"); var links = result.Take(40).Select(r => r.BoardLink); foreach (var l in links) { var o = await _store.LoadReference(l); Assert.IsNotNull(o, "Не получена информация о доске"); Assert.IsTrue(BoardLinkEqualityComparer.Instance.Equals(l, o.BoardLink), "Ссылка не соответствует исходной"); } Logger.LogMessage($"Query {cid}:{qid} finished"); return(Nothing.Value); } for (var i = 0; i < 5; i++) { Logger.LogMessage($"Cycle {i} started"); await _collection.Suspend(); Logger.LogMessage("DB suspended"); await _collection.Resume(); Logger.LogMessage("DB resumed"); var cid = i; var toWait = new Task[] { CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 1)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 2)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 3)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 4)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 5)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 6)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 7)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 8)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 9)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 10)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 11)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 12)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 13)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 14)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 15)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 16)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 17)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 18)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 19)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 20)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 21)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 22)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 23)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 24)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 25)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 26)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 27)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 28)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 29)), CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 30)), }; Logger.LogMessage($"Waiting for all queries (cycle {i})"); await Task.WhenAll(toWait); Logger.LogMessage($"Waited for all queries (cycle {i})"); } }