.Net异步编程 1

.Net异步编程 1

请大家关注我的微博:@NormanLin_BadPixel坏像素


废话不多说,先去看大神们的教程吧。

C#:异步编程和线程的使用(.NET 4.5 )

本引用文是由葡萄城控件技术开发团队发布,转载请注明出处:葡萄城控件

这里我会从大佬的原文中摘取一些我认为重要的话。

.NET中提供了三种不同的异步模式:

1. 异步编程模型(APM)模式
2. 基于事件的异步模式(EAP)
3. 基于任务的异步模式(TAP)

前两种模型微软官方并不推荐使用,本文不再详细描述。我们将详细讨论基于任务的异步模式(TAP):

在.NET 4.5中引入了异步编程模式,大部分情况下都不需要我们手动创建线程。编译器已经替代了开发人员来完成这项工作。

.NET框架引入了两个新的关键字来实现异步编程:“async”和“await”。使用 “await”的异步方法必须由“async”修饰符来声明方法。“await”关键字修饰调用异步方法。await 运算符应用于一个异步方法中的任务以挂起该方法的执行,直到等待任务完成.
而“ async ”修饰符只能用于返回值为Task类型或Void的方法。它不能用于主程序的切入点。

所有的方法之前不能使用await关键字,使用“await”关键字方法必须返回 “可等待”类型。以下属于“可等待”类型:

1. Task

2. Task

3. 自定义“可等待”类型。
1:  private async static void CallerWithAsync()// async modifier is used 
2:   
3:  { 
4:   
5:  string result = await GetSomethingAsync();// await is used before a method call. It suspends
6:     //execution of CallerWithAsync() method and control returs to the calling thread that can 
      //perform other task. 
7:   
8:  Console.WriteLine(result);
9:     // this line would not be executed before GetSomethingAsync() //method completes 
10:   
11:  } 

我觉得这段代码很重要,能帮助大家理解这里的执行顺序。大家看英语大概都能看懂。真的难以理解的,大家可以把它想象成Unity的协程。

1:  private async static void MultipleAsyncMethodsWithCombinators() 
2:   
3:  { 
4:   
5:  Task t1 = GreetingAsync("Bulbul"); 
6:   
7:  Task t2 = GreetingAsync("Ahmed"); 
8:   
9:  await Task.WhenAll(t1, t2); 
10:   
11:  Console.WriteLine("Finished both methods.\n " + 
12:   
13:  "Result 1: {0}\n Result 2: {1}", t1.Result, t2.Result); 
14:   
15:  } 

在这里,我们使用Task.WhenAll连接器。Task.WhenAll创建一个任务,将完成所有的提供的任务。Task类也有其他的结合器。Task.WhenAny,当所任务链中所有的任务完成时,结束使用。

在此之前,如果从线程池中调用线程,线程是不可能取消。现在,Task类提供了一个方法基于CancellationTokenSource类能够取消已启动的任务

对这个取消已启动的任务,我有一些疑惑,它是在调用了这个方法后就一直在监听这个CancellationToken是否结束了还是只有在调用这个方法的时候判断。所以,我在原来的代码那里,做了一些修改。

Thread.Sleep(5000);
token.ThrowIfCancellationRequested();

这段代码会在5秒后抛出The operation was canceled. 错误。

token.ThrowIfCancellationRequested();
Thread.Sleep(5000);

不会抛出错误,程序正常运行。

经过这次实验,我们确定了只有在调用token.ThrowIfCancellationRequested()这个方法的时候判断是否要抛出错误

For或ForEach方法可以在多线程中和且索引无序可以是无序的。

如果想停止并行For或ForEach方法,可通过ParallelLoopState作为参数,并根据需要打破循环的状态,跳出循环。

ParallelLoopResult result =
Parallel.For(0, 100, async (int i, ParallelLoopState pls) =>
{
  Console.WriteLine("{0}, task: {1}, thread: {2}", i,
  Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
  await Task.Delay(10);
  if (i > 5) pls.Break();
});

这段代码有点问题的,因为它是在await完之后再判断pls的break,不会起到什么作用。这样改就好理解了。

ParallelLoopResult result =
Parallel.For(0, 100, async (int i, ParallelLoopState pls) =>
{
    if (i > 5) pls.Break();
    await Task.Delay(10);
    Console.WriteLine("{0}, task: {1}, thread: {2}", i,
    Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
});

你可能感兴趣的:(ET框架个人学习笔记,.Net,异步编程)