使用demo,(.net framework 4.0 自行添加async wait 扩展库)

    class Program
{
static void Main(string[] args)
{
Console.WriteLine("主线程"+Thread.CurrentThread.ManagedThreadId);
var asyncTaskQueue = new AsyncTaskQueue
{
AutoCancelPreviousTask = true, // 自动取消之前的任务
UseSingleThread = true // 使用单线程执行任务
}; // 快速启动20个任务
for (var i = ; i < ; i++)
{
Test(asyncTaskQueue, i);
}
Console.WriteLine("运行结束");
Console.ReadKey();
} public static async void Test(AsyncTaskQueue taskQueue, int num)
{
var result = await taskQueue.Run(() =>
{
// 长时间耗时任务
Thread.Sleep();
Console.WriteLine("输入的是" + num);
return num * ;
});
Console.WriteLine("当前线程" + Thread.CurrentThread.ManagedThreadId + "输出的的" + result);
}
}

这里是实现代码

#region summary

//   ------------------------------------------------------------------------------------------------
// <copyright file="AsyncTaskQueue.cs" >
// 作者:mokeyish
// </copyright>
// ------------------------------------------------------------------------------------------------ #endregion using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks; namespace Test
{
/// <summary>
/// 异步任务队列
/// </summary>
public class AsyncTaskQueue : IDisposable
{
private bool _isDisposed;
private readonly ConcurrentQueue<AwaitableTask> _queue = new ConcurrentQueue<AwaitableTask>();
private Thread _thread;
private AutoResetEvent _autoResetEvent; /// <summary>
/// 异步任务队列
/// </summary>
public AsyncTaskQueue()
{
_autoResetEvent = new AutoResetEvent(false);
_thread = new Thread(InternalRuning) {IsBackground = true};
_thread.Start();
} private bool TryGetNextTask(out AwaitableTask task)
{
task = null;
while (_queue.Count > )
{
if (_queue.TryDequeue(out task) && (!AutoCancelPreviousTask || _queue.Count == )) return true;
task.Cancel();
}
return false;
} private AwaitableTask PenddingTask(AwaitableTask task)
{
lock (_queue)
{
Debug.Assert(task != null);
_queue.Enqueue(task);
_autoResetEvent.Set();
}
return task;
} private void InternalRuning()
{
while (!_isDisposed)
{
if (_queue.Count == )
{
_autoResetEvent.WaitOne();
}
while (TryGetNextTask(out var task))
{
if (task.IsCancel) continue; if (UseSingleThread)
{
task.RunSynchronously();
}
else
{
task.Start();
}
}
}
} /// <summary>
/// 是否使用单线程完成任务.
/// </summary>
public bool UseSingleThread { get; set; } = true; /// <summary>
/// 自动取消以前的任务。
/// </summary>
public bool AutoCancelPreviousTask { get; set; } = false; /// <summary>
/// 执行任务
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public AwaitableTask Run(Action action)
=> PenddingTask(new AwaitableTask(new Task(action, new CancellationToken(false)))); /// <summary>
/// 执行任务
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="function"></param>
/// <returns></returns>
public AwaitableTask<TResult> Run<TResult>(Func<TResult> function)
=> (AwaitableTask<TResult>) PenddingTask(new AwaitableTask<TResult>(new Task<TResult>(function))); /// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} /// <summary>
/// 析构任务队列
/// </summary>
~AsyncTaskQueue() => Dispose(false); private void Dispose(bool disposing)
{
if (_isDisposed) return;
if (disposing)
{
_autoResetEvent.Dispose();
}
_thread = null;
_autoResetEvent = null;
_isDisposed = true;
} /// <summary>
/// 可等待的任务
/// </summary>
public class AwaitableTask
{
private readonly Task _task; /// <summary>
/// 初始化可等待的任务。
/// </summary>
/// <param name="task"></param>
public AwaitableTask(Task task) => _task = task; /// <summary>
/// 任务的Id
/// </summary>
public int TaskId => _task.Id; /// <summary>
/// 任务是否取消
/// </summary>
public bool IsCancel { get; private set; } /// <summary>
/// 开始任务
/// </summary>
public void Start() => _task.Start(); /// <summary>
/// 同步执行开始任务
/// </summary>
public void RunSynchronously() => _task.RunSynchronously(); /// <summary>
/// 取消任务
/// </summary>
public void Cancel() => IsCancel = true; /// <summary>
/// 获取任务等待器
/// </summary>
/// <returns></returns>
public TaskAwaiter GetAwaiter() => new TaskAwaiter(this); /// <summary>Provides an object that waits for the completion of an asynchronous task. </summary>
[HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)]
public struct TaskAwaiter : INotifyCompletion
{
private readonly AwaitableTask _task; /// <summary>
/// 任务等待器
/// </summary>
/// <param name="awaitableTask"></param>
public TaskAwaiter(AwaitableTask awaitableTask) => _task = awaitableTask; /// <summary>
/// 任务是否完成.
/// </summary>
public bool IsCompleted => _task._task.IsCompleted; /// <inheritdoc />
public void OnCompleted(Action continuation)
{
var This = this;
_task._task.ContinueWith(t =>
{
if (!This._task.IsCancel) continuation?.Invoke();
});
}
/// <summary>
/// 获取任务结果
/// </summary>
public void GetResult() => _task._task.Wait();
}
} /// <summary>
/// 可等待的任务
/// </summary>
/// <typeparam name="TResult"></typeparam>
public class AwaitableTask<TResult> : AwaitableTask
{
/// <summary>
/// 初始化可等待的任务
/// </summary>
/// <param name="task">需要执行的任务</param>
public AwaitableTask(Task<TResult> task) : base(task) => _task = task; private readonly Task<TResult> _task; /// <summary>
/// 获取任务等待器
/// </summary>
/// <returns></returns>
public new TaskAwaiter GetAwaiter() => new TaskAwaiter(this); /// <summary>
/// 任务等待器
/// </summary>
[HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)]
public new struct TaskAwaiter : INotifyCompletion
{
private readonly AwaitableTask<TResult> _task; /// <summary>
/// 初始化任务等待器
/// </summary>
/// <param name="awaitableTask"></param>
public TaskAwaiter(AwaitableTask<TResult> awaitableTask) => _task = awaitableTask; /// <summary>
/// 任务是否已完成。
/// </summary>
public bool IsCompleted => _task._task.IsCompleted; /// <inheritdoc />
public void OnCompleted(Action continuation)
{
var This = this;
_task._task.ContinueWith(t =>
{
if (!This._task.IsCancel) continuation?.Invoke();
});
} /// <summary>
/// 获取任务结果。
/// </summary>
/// <returns></returns>
public TResult GetResult() => _task._task.Result;
}
}
}
}

c# 异步任务队列(可选是否使用单线程执行任务,以及自动取消任务)的更多相关文章

  1. 异步任务队列Celery在Django中的使用

    前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...

  2. Django使用Celery异步任务队列

    1  Celery简介 Celery是异步任务队列,可以独立于主进程运行,在主进程退出后,也不影响队列中的任务执行. 任务执行异常退出,重新启动后,会继续执行队列中的其他任务,同时可以缓存停止期间接收 ...

  3. Swoole来实现实时异步任务队列

    假如要发100封邮件,for循环100遍,用户直接揭竿而起,什么破网站!但实际上,我们很可能有超过1万的邮件.怎么处理这个延迟的问题?答案就是用异步.把“发邮件”这个操作封装,然后后台异步地执行1万遍 ...

  4. PHP使用swoole来实现实时异步任务队列

    转载来自第七星尘的技术博客的<PHP使用swoole来实现实时异步任务队列> 关于异步任务队列 用户打开了我们的网站.他要做的就是勾选需要发邮件的代理商列表,然后把结算邮件发出去.假如我们 ...

  5. redis实现异步任务队列

    redis实现异步任务队列 先说思路: 将任务对象序列为JSON字符串,然后推入REDIS缓存,这叫入队. 通过独立的工作线程从REDIS拉出一个任务,这叫出队,工作线程将JSON字符串还原为任务对象 ...

  6. 用swoole实现异步任务队列

    应用场景如下: 假如要发100封邮件,for循环100遍,这种方法显然是不可取的. 在一些比较繁杂的业务里,我们很可能有超过1万的邮件要群发.那我们怎么处理这个延迟的问题? 答案就是用异步.把&quo ...

  7. Asp-Net-Core开发笔记:集成Hangfire实现异步任务队列和定时任务

    前言 最近把Python写的数据采集平台往.Net Core上迁移,原本的采集任务使用多进程+线程池的方式来加快采集速度,使用Celery作为异步任务队列兼具定时任务功能,这套东西用着还行,但反正就折 ...

  8. .NET C#-- 利用BeginInvoke与EndInvoke完成异步委托方法并获取方法执行返回值示例

    //定义委托 delegate string MyDelegate(string name); //定义委托调用函数 public string Hello(string name) { Thread ...

  9. Orleans的单线程执行模型

    Orleans在默认情况下只创建一个grain的实例,并以单线程模型执行.如果同一个grain实例,在Orleans存在多个实例,就会产生并发冲突,单线程执行模型就可以完全避免并发冲突了. 但在特殊场 ...

随机推荐

  1. 关于JsonArray与JsonObject的使用

    学习地址:http://blog.csdn.net/lishuangzhe7047/article/details/28880009 关于前台向后台传递数组(里面包含json格式) [{"i ...

  2. shell脚本—基础知识,变量

    shell脚本本质: 编译型语言 解释型语言 shell编程基本过程 1.建立shell文件 2.赋予shell文件执行权限,使用chmod命令修改权限 3.执行shell文件 shell变量: sh ...

  3. flex记忆

    ._rebate { display: -webkit-box; display: -moz-box; display: -webkit-flex; display: -moz-flex; displ ...

  4. Windows下Jupyter notebook 修改默认打开(工作、保存)文件夹(路径)

    今天晚上兴致一起突然想看看我写了那么多的ipynb文件都去哪了 首先查了一下,应该是都默认保存到    C:\Users\芩溪儿   路径下了 然后我就想,我是不是得改改啊,总在那跟别的文件夹在一起总 ...

  5. 01 c++常见面试题总结

    https://www.cnblogs.com/yjd_hycf_space/p/7495640.html   C++常见的面试题 http://c.tedu.cn/workplace/217749. ...

  6. Python检测删除你的好友-wxpy模块(发送特殊字符式)

    下面是代码: from wxpy import *import timeprint("本软件采用特殊字符检测,即对方收不到任何信息!")print("或许某个版本微信就会 ...

  7. PAT 1080. Graduate Admission

    It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applicat ...

  8. COOKIE, SESSION, JSESSION

    http://www.360doc.com/content/11/1027/10/7472437_159535413.shtml

  9. HDU 4456 Crowd

    Crowd Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  10. Solr Update插件自定义Update Chain按条件更新索引

    背景:基于call客,来电和跟进记录等多个数据来源的用户文档,需要在更新是判断首来源的时间. 如对电话号码11xxxx来说,来电时间是今天,call客时间是昨天,而call客数据又可能因为网络原因晚上 ...