C# 从外部取消任务的执行

    根据微软官方文档,推荐用TAP模式编写异步程序,提供了用于取消Task的 CancellationToken 标记,实际应用中可以new 一个CancellationTokenSource对象。当我们需要一个循环执行的机制时(在Thread方式下通常是用Thread.Sleep,在Task下就是await Task.Delay),需要停下来时,由于线程或Task从外部都是无法停止的,要在内部通过这个 CancellationToken 来自行停下来, 那么就有两个选择:

  1.  每次循环开始时,使用 cancellationToken.IsCancellationRequested 判断要不要停下来;
  2. 在Task.Delay里面加上cancellationToken参数,然后截获Task.Delay抛出的 OperationCanceledException 异常。

  以Delay 50ms为例,测试结果表明,Cancel前等待时间 方法1要短于方法2,估计方法2的 throw-try-catch 代价比较高,推荐使用方法1

    方法1,只通过 IsCancellationRequested 测试:

static void Main(string[] args)
{
	System.Threading.CancellationTokenSource quitFlag = new System.Threading.CancellationTokenSource();
	testCancel1(quitFlag.Token);
	Task.Delay(250).Wait();
	Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff") + " Cancel...");
	quitFlag.Cancel();
	Console.Read();
}

static async void testCancel1(System.Threading.CancellationToken cancellationToken)
{
	while (!cancellationToken.IsCancellationRequested)
	{
		Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff"));
		await Task.Delay(50);
	}
	Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff") + " Cancelled");
}
//09:50:18 286
//09:50:18 413
//09:50:18 474
//09:50:18 527
//09:50:18 587
//09:50:18 603 Cancel...
//09:50:18 649 Cancelled

     方法2,通过 IsCancellationRequested 和 Delay(50,cancellationToken) 截获异常:

static void Main(string[] args)
{
	System.Threading.CancellationTokenSource quitFlag = new System.Threading.CancellationTokenSource();
	testCancel1(quitFlag.Token);
	Task.Delay(250).Wait();
	Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff") + " Cancel...");
	quitFlag.Cancel();
	Console.Read();
}

static async void testCancel2(System.Threading.CancellationToken cancellationToken)
{
	try
	{
		while (!cancellationToken.IsCancellationRequested)
		{
			Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff"));
			await Task.Delay(50, cancellationToken);
		}
		Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff") + " Cancelled");
	}
	catch(OperationCanceledException ex)
	{
		Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff") + " Throwed");
	}
}
//09:53:50 718
//09:53:50 843
//09:53:50 900
//09:53:50 964
//09:53:51 029
//09:53:51 031 Cancel...
//09:53:51 808 Throwed

       

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我理解了你的问题。你想知道如何在C# Furion指定一个特定的时间来执行任务。 在C# Furion,你可以使用.NET Framework的`System.Timers.Timer`类来实现定时任务。你可以创建一个`Timer`对象,并设置它的`Interval`属性为`0`,然后在`Elapsed`事件检查当前时间是否等于或超过指定的时间,如果是,则执行任务。 以下是一个示例代码,展示如何在C# Furion指定时间执行任务: ``` csharp using System; using System.Timers; class Program { static void Main() { // 创建一个 Timer 对象 Timer timer = new Timer(); // 设置 Timer 的间隔为 0 毫秒 timer.Interval = 0; // 设置 Timer 的 AutoReset 属性为 false,以便 Timer 只触发一次 timer.AutoReset = false; // 设置要执行任务的时间 DateTime taskTime = new DateTime(2022, 12, 31, 23, 59, 59); // 添加 Timer 的 Elapsed 事件处理程序 timer.Elapsed += (sender, e) => { // 检查当前时间是否等于或超过任务时间 if (DateTime.Now >= taskTime) { // 到达任务时间,执行任务 Console.WriteLine("任务已经开始执行!"); } else { // 如果当前时间还没到达任务时间,重新启动 Timer timer.Start(); } }; // 启动 Timer timer.Start(); // 阻塞主线程,以便 Timer 有足够时间触发 Elapsed 事件 Console.ReadLine(); } } ``` 在这个示例代码,我们首先创建了一个`Timer`对象,并将它的`Interval`属性设置为`0`,表示让`Timer`立即触发`Elapsed`事件。然后,我们设置了要执行任务的时间,并添加了`Elapsed`事件的处理程序。在`Elapsed`事件,我们检查当前时间是否等于或超过指定的时间。如果是,我们就执行任务。如果还没有到达任务时间,我们就重新启动`Timer`,以便在到达任务时间时再次触发`Elapsed`事件。 当然,这只是一个简单的示例,你可以根据你的具体需求来修改代码。但这个示例将会给你提供一个基本的思路,来在C# Furion指定时间执行任务

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值