c# taskscheduler使用场合_hbase shell put
大家好,又见面了,我是你们的朋友全栈君。
这里记录下 TaskScheduler 的简单用法。
使用场景:
使用 Task 的时候,大家知道用 TaskFactory.StartNew 可以用来创建一个 Task 。这里如果创建了 3 个,那么这3个 Task 就各自放飞直接运行了。
class Program
{
private static TaskFactory _taskFactory;
static void Main(string[] args)
{
_taskFactory = new TaskFactory();
_taskFactory.StartNew(Func1);
_taskFactory.StartNew(Func2);
_taskFactory.StartNew(Func3);
Console.ReadLine();
}
static void Func1()
{
Thread.Sleep(3000);
Console.WriteLine("Func1");
}
static void Func2()
{
Thread.Sleep(2000);
Console.WriteLine("Func2");
}
static void Func3()
{
Thread.Sleep(1000);
Console.WriteLine("Func3");
}
}
结果:
Func3
Func2
Func1
一般情况下没什么大问题,但如果这3个中的每个Task都非常耗CPU或者内存,而计算机又需要预留资源去干别的事情,这就要让3个Task不能同时执行。又或者确实要让某些Task先做,有些后做。这就需要我们自己能够决定Task执行顺序。
怎样达到这样的效果?
答案就是:TaskScheduler,它可以让已经创建好的 Task 去按照特殊的顺序来执行。
就拿上面的场景来举例:
为了节约系统资源,我要让这3个Task单独执行,有一个在执行,其它俩就不能执行。最简单的就是串行执行,这样只需要写一个类继承TaskScheduler:
public class MyTaskScheduler : TaskScheduler, IDisposable
{
private static readonly object _mutex = new object();
public readonly List<Task> _currentTasks = new List<Task>();
private readonly ManualResetEvent[] _schedulerEvents = new ManualResetEvent[2];
public override int MaximumConcurrencyLevel => 1;
public MyTaskScheduler()
{
_schedulerEvents[0] = new ManualResetEvent(false);
_schedulerEvents[1] = new ManualResetEvent(false);
var executionThread = new Thread(ExecutionThread) { Name = "MyThread" };
executionThread.SetApartmentState(ApartmentState.MTA);
executionThread.IsBackground = true;
executionThread.Priority = ThreadPriority.Normal;
executionThread.Start(null);
}
public void Dispose()
{
_schedulerEvents[1].Set();
}
private void ExecutionThread(object args)
{
try
{
while (true)
{
if (!WaitIfEmpty())
{
break;
}
Task task;
lock (_mutex)
{
task = _currentTasks[0];
}
try
{
TryExecuteTask(task);
}
catch (Exception)
{
throw;
}
finally
{
TryDequeue(task);
}
}
}
finally
{
//todo
}
}
private bool WaitIfEmpty()
{
lock (_mutex)
{
if (_currentTasks.Count == 0)
{
//pause task
_schedulerEvents[0].Reset();
}
}
//wait any signal.
int id = WaitHandle.WaitAny(_schedulerEvents);
// id is item index of _schedulerEvents
return id == 0;
}
protected override IEnumerable<Task>? GetScheduledTasks()
{
lock (_mutex)
{
return _currentTasks.ToArray();
}
}
protected override void QueueTask(Task task)
{
lock (_mutex)
{
_currentTasks.Add(task);
if (_currentTasks.Count > 0)
{
// Start task
_schedulerEvents[0].Set();
}
}
}
protected sealed override bool TryDequeue(Task task)
{
lock (_mutex)
{
var res = _currentTasks.Remove(task);
return res;
}
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return false;
}
}
主函数中只要稍作修改:
static void Main(string[] args)
{
var taskScheduler = new MyTaskScheduler();
_taskFactory = new TaskFactory(taskScheduler);
_taskFactory.StartNew(Func1);
_taskFactory.StartNew(Func2);
_taskFactory.StartNew(Func3);
Console.ReadLine();
}
运行结果:
Func1
Func2
Func3
在MyTaskScheduler 中,我建了一个线程 executionThread,线程方法是一个while循环,一直在监听有没有新的Task过来,有多个Task过来,就按Task创建顺序执行,没有的话 while 就暂停在 waitany 处。
这样的场景,配合 ManualResetEvent 和Task的CancellationTokenSource 非常适合做 带有暂停和取消功能的任务列表。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183039.html原文链接:https://javaforall.cn
相关文章
- c#数组赋初值_C#数组初始化
- 【说站】C#在PDF中添加墨迹注释Ink Annotation的步骤详解
- 最新C#调用Google即时翻译
- c# mysql executenonquery_C#与数据库访问技术之ExecuteNonQuery方法
- 看我是如何用C#编写一个小于8KB的贪吃蛇游戏的
- c# 多线程并发-金三银四面试:C#.NET面试题高级篇2-多线程
- c#面试题抽象类和接口的区别-金三银四面试:C#程序员经常遇到的30道基础面试题,想你所想
- C# 使用throw;throw ex;和 throw new Exception();抛异常区别与建议
- C#三层架构和MVC的区别详解架构师
- Hbase(二)hbase建表详解大数据
- Hbase(七)hbase高级编程详解大数据
- Spring Boot 2.x :通过 spring-boot-starter-hbase 集成 HBase
- C#怎样才能实现窗体最小化到托盘呢?
- 用C#操纵IIS(代码)
- C#学习基础概念二十五问11-15
- c#实现16进制和字符串之间转换的代码
- c#重载WndProc,实现重写“最小化”的实现方法
- C#中一些你可能没用过的调试窗口的方法
- C#中遍历各类数据集合的方法总结
- C#文件操作的简单实例
- c#使用ManagedWifi查看当前Wifi信号并选择wifi的示例
- C#执行SQL事务用法实例
- C#自定义函数NetxtString生成随机字符串
- C#使用iCSharpcode进行文件压缩实现方法