使用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. 【转载】使用JSONObject生成和解析json

    1. json数据类型 类型 描述 Number 数字型 String 字符串型 Boolean 布尔型 Array 数组 Object 对象 null 空值 (1)json中不区分整数.小数等类型, ...

  2. eas之MrpUI

    package com.kingdee.eas.custom.mrp.client; import java.awt.Component;import java.awt.event.*;import ...

  3. [系统资源攻略]memory

    内存 这里的讲到的 "内存" 包括物理内存和虚拟内存,虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一 ...

  4. eslint 校验去除

    不允许对 function 的参数进行重新赋值 /* eslint no-param-reassign: ["error", { "props": false ...

  5. UNIX C 进程Part2

    1.获取进程ID #include <unistd.h> pid_t getpid(void); //获取子进程id pid_t getppid(void);//获取父进程id 2.获取实 ...

  6. 继续聊WPF——进度条

    ProgressBar控件与传统WinForm使用方法完全一样,我们只需关注: Minimum——最小值,默认为0: Maximum——最大值,默认为100. Value——当前值.   关键是它的控 ...

  7. 调用的方法里接收一个List<>类型的参数,里面是自定义的EC类, 我要通过反射构建这List对象

              public static object CreateGeneric(Type generic, Type innerType, params object[] args)     ...

  8. cxdbtreelist的按记录查找节点

    lst_projet.DataController.DataSet.Locate('pm_id',vPm_ID,[]); bl:= lst_projet.DataController.DataSet. ...

  9. 运行npm run watch时报:events.js:182 throw er; // Unhandled 'error' event

    I had this issue i did the following steps and i have no issues anymore: Delete node_modules directo ...

  10. EXPLAIN sql优化方法(1) 添加索引

    添加索引优化器更高效率地执行语句 假设我们有两个数据表t1和t2,每个有1000行,包含的值从1到1000.下面的查询查找出两个表中值相同的数据行: mysql> SELECT t1.i1, t ...