C#多线程系列之任务基础(三)_第1页
C#多线程系列之任务基础(三)_第2页
C#多线程系列之任务基础(三)_第3页
C#多线程系列之任务基础(三)_第4页
C#多线程系列之任务基础(三)_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C#多线程系列之任务基础(三)Task.FromCanceled()

微软文档解释:创建Task,它因指定的取消标记进行的取消操作而完成。

这里笔者抄来了一个示例:

vartoken=newCancellationToken(true);

Tasktask=Task.FromCanceled(token);

TaskintgenericTask=Task.FromCanceledint(token);

网上很多这样的示例,但是,这个东西到底用来干嘛的?new就行了?

带着疑问我们来探究一下,来个示例:

publicstaticTaskTest()

CancellationTokenSourcesource=newCancellationTokenSource();

source.Cancel();

returnTask.FromCanceledobject(source.Token);

staticvoidMain()

vart=Test();//在此设置断点,监控变量

Console.WriteLine(t.IsCanceled);

}

Task.FromCanceled()可以构造一个被取消的任务。我找了很久,没有找到很好的示例,如果一个任务在开始前就被取消,那么使用Task.FromCanceled()是很不错的。

这里有很多示例可以参考:/csharp-examples/System.Threading.Tasks.Task.FromCanceled(System.Threading.CancellationToken)/

如何在内部取消任务

之前我们讨论过,使用CancellationToken取消令牌传递参数,使任务取消。但是都是从外部传递的,这里来实现无需CancellationToken就能取消任务。

我们可以使用CancellationToken的ThrowIfCancellationRequested()方法抛出System.OperationCanceledException异常,然后终止任务,任务会变成取消状态,不过任务需要先传入一个令牌。

这里笔者来设计一个难一点的东西,一个可以按顺序执行多个任务的类。

示例如下:

///summary

///能够完成多个任务的异步类型

////summary

publicclassMyTaskClass

privateListAction_actions=newListAction

privateCancellationTokenSource_source=newCancellationTokenSource();

privateCancellationTokenSource_sourceBak=newCancellationTokenSource();

privateTask_task;

///summary

///添加一个任务

////summary

///paramname="action"/param

publicvoidAddTask(Actionaction)

_actions.Add(action);

///summary

///开始执行任务

////summary

///returns/returns

publicTaskStartAsync()

//_=newTask()对本示例无效

_task=Task.Factory.StartNew(()=

for(inti=0;i_actions.Count;i++)

inttmp=i;

Console.WriteLine($"第{tmp}个任务");

if(_source.Token.IsCancellationRequested)

Console.ForegroundColor=ConsoleColor.Red;

Console.WriteLine("任务已经被取消");

Console.ForegroundColor=ConsoleColor.White;

_sourceBak.Cancel();

_sourceBak.Token.ThrowIfCancellationRequested();

_actions[tmp].Invoke();

},_sourceBak.Token);

return_task;

///summary

///取消任务

////summary

///returns/returns

publicTaskCancel()

_source.Cancel();

//这里可以省去

_task=Task.FromCanceledobject(_source.Token);

return_task;

}

Main方法中:

staticvoidMain()

//实例化任务类

MyTaskClassmyTask=newMyTaskClass();

for(inti=0;ii++)

inttmp=i;

myTask.AddTask(()=

Console.WriteLine("任务1Start");

Thread.Sleep(TimeSpan.FromSeconds(1));

Console.WriteLine("任务1End");

Thread.Sleep(TimeSpan.FromSeconds(1));

//相当于Task.WhenAll()

Tasktask=myTask.StartAsync();

Thread.Sleep(TimeSpan.FromSeconds(1));

Console.WriteLine($"任务是否被取消:{task.IsCanceled}");

//取消任务

Console.ForegroundColor=ConsoleColor.Red;

Console.WriteLine("按下任意键可以取消任务");

Console.ForegroundColor=ConsoleColor.White;

Console.ReadKey();

vart=myTask.Cancel();//取消任务

Thread.Sleep(TimeSpan.FromSeconds(2));

Console.WriteLine($"任务是否被取消:【{task.IsCanceled}】");

Console.ReadKey();

}

你可以在任一阶段取消任务。

Yield关键字

迭代器关键字,使得数据不需要一次性返回,可以在需要的时候一条条迭代,这个也相当于异步。

迭代器方法运行到yieldreturn语句时,会返回一个expression,并保留当前在代码中的位置。下次调用迭代器函数时,将从该位置重新开始执行。

可以使用yieldbreak语句来终止迭代。

官方文档:/zh-cn/dotnet/csharp/language-reference/keywords/yield

网上的示例大多数都是foreach的,有些同学不理解这个到底是啥意思。笔者这里简单说明一下。

我们也可以这样写一个示例:

这里已经没有foreach了。

privatestaticint[]list=newint[]{1,2,3,4,5,6,7,8,9};

privatestaticIEnumerableintForAsync()

inti=0;

while(ilist.Length)

i++;

yieldreturnlist[i];

}

但是,同学又问,这个return返回的对象要实现这个IEnumerableT才行嘛?那些文档说到什么迭代器接口什么的,又是什么东西呢?

我们可以先来改一下示例:

privatestaticint[]list=newint[]{1,2,3,4,5,6,7,8,9};

privatestaticIEnumerableintForAsync()

inti=0;

while(ilist.Length)

intnum=list[i];

i++;

yieldreturnnum;

}

你在Main方法中调用,看看是不是正常运行?

staticvoidMain()

foreach(variteminForAsync())

Console.WriteLine(item);

Console.ReadKey();

}

这样说明了,yieldreturn返回的对象,并不需要实现IEnumerableint方法。

其实yield是语法糖关键字,你只要在循环中调用它就行了。

staticvoidMain()

foreach(variteminForAsync())

Console.WriteLine(item);

Console.ReadKey();

privatestaticIEnumerableintForAsync()

inti=0;

while(i100)

i++;

yieldreturni;

}

它会自动生成IEnumerableT,而不需要你先实现IEnumerableT。

补充知识点

线程同步有多种方法:临界区(CriticalSection)、互斥量(Mutex)、信号量(Semaphor

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论