gpt4 book ai didi

c# - 使用 tasks 和 ContinueWith 实现调度器

转载 作者:行者123 更新时间:2023-11-30 20:49:35 26 4
gpt4 key购买 nike

我正在尝试编写自己的调度程序;其背后的基本原理是所有提交的 Action 将根据延迟按顺序执行。例如,如果在时间 0 我安排了延迟 5 的操作 A 并且在时间 1 我安排了操作 B 延迟 2,然后 B 应该在时间 3A 处首先执行应该在时间 5 时执行第二个。

基本上,我想做的是:

public class MyScheduler
{
Task _task = new Task(() => { });

public MyScheduler()
{
_task.Start();
}

public void Schedule(Action action, long delay)
{
Task.Delay(TimeSpan.FromTicks(delay)).ContinueWith(_ =>
lock(_task) {
_task = _task.ContinueWith(task => action())
}
);
}

}

此代码的相关测试是:

 var waiter = new Waiter(3);
int _count = 0;
mysched = new MyScheduler();
mysched.Schedule(() => { _count++; waiter.Signal(); });
mysched.Schedule(() => { Task.Delay(100).Wait(); _count *= 3; waiter.Signal(); });
mysched.Schedule(() => { _count++; waiter.Signal(); });

waiter.Await();
Assert.AreEqual(4, _count);

上面代码中,Waiter是一个在构造函数中初始化了内部变量的类; Signal 方法递减该内部变量,Await 方法循环(每次迭代休眠 10 毫秒)直到内部变量小于或等于零。

测试的目的是表明计划的操作已按顺序执行。

大多数情况下这是正确的并且测试通过,但在少数情况下 _count 的结果值为 2 而不是 4 .我花了很多时间试图弄清楚为什么会发生这种情况,但我似乎无法弄清楚,而且我缺乏 C# 经验也无济于事。

有人有什么建议吗?

最佳答案

一方面,_count 对于不同线程的访问是不同步的。

我建议您根本不要使用 ContinueWith;这是一个非常底层的方法,很容易弄错细节(例如,默认调度程序是 TaskScheduler.Current,这几乎不是您想要的)。您的一般逻辑代码应使用 await 而不是 ContinueWith

关于调度器,现在几乎不可能为自己开发一个好的用例。有更好的可用的,它们是由天才开发的并且经过了非常好的测试。考虑 Reactive Extensions:它们提供了多个调度程序,而且它们都是 support scheduling .

关于c# - 使用 tasks 和 ContinueWith 实现调度器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23437048/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com