Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
[TestMethod]
public void ExecTaskTest()
{
using (var disp = new TaskDispatcher())
{
DateTime now = DateTime.Now;
DateTime? time = null;
disp.Add(TimeSpan.FromSeconds(1), () => time = DateTime.Now);
Thread.Sleep(TimeSpan.FromSeconds(2));
Assert.IsTrue(time - now > TimeSpan.FromSeconds(1));
}
}
[TestMethod]
public void ExecTwoTaskTest()
{
using (var disp = new TaskDispatcher())
{
DateTime now = DateTime.Now;
DateTime? time0 = null;
DateTime? time1 = null;
disp.Add(TimeSpan.FromSeconds(1), () => time0 = DateTime.Now);
Thread.Sleep(TimeSpan.FromSeconds(2));
disp.Add(TimeSpan.FromSeconds(1), () => time1 = DateTime.Now);
Assert.IsTrue(time0 - now > TimeSpan.FromSeconds(1));
Assert.IsTrue(time1 - time0 > TimeSpan.FromSeconds(1));
}
}
[TestMethod]
public void ReplaceTaskTest()
{
using (var disp = new TaskDispatcher())
{
DateTime now = DateTime.Now;
DateTime? time0 = null;
DateTime? time1 = null;
disp.Add(TimeSpan.FromSeconds(2), () => time0 = DateTime.Now);
Thread.Sleep(TimeSpan.FromSeconds(1));
disp.Add(TimeSpan.FromSeconds(2), () => time1 = DateTime.Now);
Thread.Sleep(TimeSpan.FromSeconds(3));
Assert.IsNull(time0);
Assert.IsTrue(time1 - now > TimeSpan.FromSeconds(3));
}
}
[TestMethod]
public void AddSomeTimeTwoTaskTest()
{
using (var disp = new TaskDispatcher())
{
DateTime now = DateTime.Now;
DateTime? time0 = null;
DateTime? time1 = null;
//как-то и где-то в отдельных потоках
disp.Add(TimeSpan.FromSeconds(1), () => time0 = DateTime.Now);
disp.Add(TimeSpan.FromSeconds(1), () => time1 = DateTime.Now);
Thread.Sleep(TimeSpan.FromSeconds(2));
//только один не null
Assert.IsTrue((time0 != null) != (time1 != null));
}
}
[TestMethod]
public void AddSomeTimeTwoTaskTest()
{
using (var disp = new TaskDispatcher())
{
DateTime now = DateTime.Now;
DateTime? time0 = null;
DateTime? time1 = null;
//как-то и где-то в отдельных потоках
disp.Add(TimeSpan.FromSeconds(1), () => time0 = DateTime.Now);
disp.Add(TimeSpan.FromSeconds(1), () => time1 = DateTime.Now);
Thread.Sleep(TimeSpan.FromSeconds(2));
//только один не null
Assert.IsTrue((time0 != null) != (time1 != null));
}
}
[TestMethod]
public void AddNewFromEndFirstTest()
{
using (var disp = new TaskDispatcher())
{
DateTime now = DateTime.Now;
DateTime? time0 = null;
DateTime? time1 = null;
disp.Add(TimeSpan.FromSeconds(1), () => time0 = DateTime.Now);
//где-то точно (точно во время схватывания первой задачи)
Thread.Sleep(TimeSpan.FromSeconds(1));
disp.Add(TimeSpan.FromSeconds(1), () => time1 = DateTime.Now);
//только один не null
Assert.IsTrue((time0 != null) != (time1 != null));
}
}
var t = new Task(() => worker(task, _currentTaskCancellation.Token), _currentTaskCancellation.Token);
t.Start();
<source>
Приоретизация действительно не решена:
<source lang="cs">
[TestMethod]
public void MultipleTasks_ShouldQueueInSequence()
{
var timeService = new TimeServiceStub();
var queue = new QueueMock();
var target = new DelayedExecution(timeService, queue);
var task1 = new TaskStub();
var task2 = new TaskStub();
target.Add(task1);
timeService.Wait(t/2);
target.Add(task2);
timeService.Wait(t);
queue.AssertEnqueuedOnlyOne(task2);
}
[TestMethod]
public void ExecTaskTest()
{
using (var disp = new TaskDispatcher())
{
DateTime add = DateTime.Now;
var execLog = new List<DateTime>();
Action addTask = () =>
disp.Add(TimeSpan.FromSeconds(1),
() =>
{
execLog.Add(DateTime.Now);
Breakpoint.Define("exec");
});
new ThreadTestManager(TimeSpan.FromSeconds(2), addTask).Run("exec");
Assert.IsTrue(execLog.Single() - add > TimeSpan.FromSeconds(1));
}
}
[TestMethod]
public void ExecTwoTaskTest()
{
using (var disp = new TaskDispatcher())
{
var log = new List<int>();
Action act = () =>
{
disp.Add(TimeSpan.FromSeconds(1), () => { log.Add(0); Breakpoint.Define("exec0"); });
Breakpoint.Define("pause");
disp.Add(TimeSpan.FromSeconds(1), () => { log.Add(1); Breakpoint.Define("exec1"); });
};
new ThreadTestManager(TimeSpan.FromSeconds(3), act).Run("exec0", "pause", "exec1");
Assert.AreEqual(2, log.Count);
Assert.AreEqual(0, log[0]);
Assert.AreEqual(1, log[1]);
}
}
[TestMethod]
public void ReplaceTaskTest()
{
using (var disp = new TaskDispatcher())
{
var log = new List<int>();
Action act = () =>
{
disp.Add(TimeSpan.FromSeconds(1), () => { log.Add(0); Breakpoint.Define("exec"); });
disp.Add(TimeSpan.FromSeconds(1), () => { log.Add(1); Breakpoint.Define("exec"); });
};
new ThreadTestManager(TimeSpan.FromSeconds(3), act).Run(
"exec", new BreakMark("exec") { Timeout = true });
Assert.AreEqual(1, log.Count);
Assert.AreEqual(1, log[0]);
}
}
class TaskDispatcher : IDisposable
{
EventWaitHandle m_oldCancelEv;
public TaskDispatcher()
{
m_oldCancelEv = new AutoResetEvent(false);
}
void Run(EventWaitHandle cancelEv, TimeSpan delay, Action act)
{
if (!cancelEv.WaitOne(delay))
act();
}
public void Add(TimeSpan delay, Action act)
{
m_oldCancelEv.Set();
var newCancelEv = new AutoResetEvent(false);
var task = new Task(() => Run(newCancelEv, delay.Ticks > 0 ? delay : TimeSpan.Zero, act));
task.Start();
m_oldCancelEv = newCancelEv;
}
public void Dispose()
{
m_oldCancelEv.Set();
}
}
[TestMethod]
public void SyncCancelPrevTaskTest()
{
using (var disp = new TaskDispatcher())
{
Action act0 = () => disp.Add(TimeSpan.Zero, () => { });
Action act1 = () => disp.Add(TimeSpan.Zero, () => { });
new ThreadTestManager(TimeSpan.FromSeconds(1), act0, act1).Run(
new BreakMark(act0, "precancel prev task"),
new BreakMark(act1, "precancel prev task") { Timeout = true },
new BreakMark(act0, "finish add"));
}
}
class TaskDispatcher : IDisposable
{
object m_syncAdd = new object();
...
public void Add(TimeSpan delay, Action act)
{
lock (m_syncAdd)
{
Breakpoint.Define("precancel prev task");
m_oldCancelEv.Set();
var newCancelEv = new AutoResetEvent(false);
var task = new Task(() => Run(newCancelEv, delay.Ticks > 0 ? delay : TimeSpan.Zero, act));
task.Start();
m_oldCancelEv = newCancelEv;
Breakpoint.Define("finish add");
}
}
}
new BreakMark(act0, "precancel prev task"),
new BreakMark(act1, "precancel prev task") { Timeout = true },
new BreakMark(act0, "finish add")
Тестирование параллельных потоков