取消作业
到目前为止显示的两个Mandelbrot程序仅用于生成单个图像,因此一旦启动它就不可能取消该作业。但是,在一般情况下,您需要为用户提供一种便利,以摆脱冗长的后台作业。
尽管您可以将自己的一个取消系统放在一起,但System.Threading命名空间已经为您提供了一个名为CancellationTokenSource的类和一个名为CancellationToken的结构。
以下是它的工作原理:
程序创建一个CancellationTokenSource以用于特定的异步方法。 CancellationTokenSource类定义名为Token的属性,该属性返回CancellationToken。此CancellationToken值将传递给异步方法。异步方法定期调用CancellationToken的IsCancellationRequested方法。此方法通常返回false。
当程序想要取消异步操作时(可能是响应某些用户输入),它调用CancellationTokenSource的Cancel方法。下次异步方法调用CancellationToken的IsCancellationRequested方法时,该方法返回true,因为已请求取消。异步方法可以选择如何
停止运行,也许是一个简单的return语句。
然而,通常采用不同的方法。异步方法可以简单地调用ThrowIfCancellationRequested方法,而不是调用CancellationToken的IsCancellationRequested方法。如果已请求取消,则异步方法将通过引发OperationCanceledException停止执行。
这意味着await运算符必须是try块的一部分,但正如您所见,这通常是处理文件时的情况,因此它不会添加太多额外的代码,并且程序可以简单地处理取消另一种形式的例外。
MandelbrotCancellation程序演示了这种技术。 XAML文件现在有第二个按钮,标记为“取消”,最初被禁用:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"x:Class="MandelbrotCancellation.MandelbrotCancellationPage"><ContentPage.Padding><OnPlatform x:TypeArguments="Thickness"iOS="0, 20, 0, 0" /></ContentPage.Padding><StackLayout><Grid VerticalOptions="FillAndExpand"><ContentView Padding="10, 0"VerticalOptions="Center"><ProgressBar x:Name="progressBar" /></ContentView><Image x:Name="image" /></Grid><Grid><Button x:Name="calculateButton"Grid.Column="0"Text="Calculate"FontSize="Large"HorizontalOptions="Center"Clicked="OnCalculateButtonClicked" /><Button x:Name="cancelButton"Grid.Column="1"Text="Cancel"FontSize="Large"IsEnabled="False"HorizontalOptions="Center"Clicked="OnCancelButtonClicked" /></Grid></StackLayout>
</ContentPage>

代码隐藏文件现在有一个更广泛的OnCalculateButtonClicked方法。 首先禁用“计算”按钮并启用“取消”按钮。 它创建一个新的Cancellation TokenSource对象,并将Token属性传递给CalculateMandelbrotAsync。 OnCancelButtonClicked方法负责在CancellationTokenSource对象上调用Cancel。 CalculateMandelbrotAsync方法以与报告进度相同的速率调用ThrowIfCancellationRequested方法。 OnCalculateButtonClicked方法捕获异常,该方法通过重新启用“计算”按钮进行另一次尝试来响应:

public partial class MandelbrotCancellationPage : ContentPage
{static readonly Complex center = new Complex(-0.75, 0);static readonly Size size = new Size(2.5, 2.5);const int pixelWidth = 1000;const int pixelHeight = 1000;const int iterations = 100;Progress<double> progressReporter;CancellationTokenSource cancelTokenSource;public MandelbrotCancellationPage(){InitializeComponent();progressReporter = new Progress<double>((double value) =>{progressBar.Progress = value;});}async void OnCalculateButtonClicked(object sender, EventArgs args){// Configure the UI for a background process.calculateButton.IsEnabled = false;cancelButton.IsEnabled = true;cancelTokenSource = new CancellationTokenSource();try{// Render the Mandelbrot set on a bitmap.BmpMaker bmpMaker = await CalculateMandelbrotAsync(progressReporter, cancelTokenSource.Token);image.Source = bmpMaker.Generate();}catch (OperationCanceledException){calculateButton.IsEnabled = true;progressBar.Progress = 0;}catch (Exception){// Shouldn't occur in this case.}cancelButton.IsEnabled = false;}void OnCancelButtonClicked(object sender, EventArgs args){cancelTokenSource.Cancel();}Task<BmpMaker> CalculateMandelbrotAsync(IProgress<double> progress, CancellationToken cancelToken){return Task.Run<BmpMaker>(() =>{BmpMaker bmpMaker = new BmpMaker(pixelWidth, pixelHeight);for (int row = 0; row < pixelHeight; row++){double y = center.Imaginary - size.Height / 2 + row * size.Height / pixelHeight;// Report the progress.progress.Report((double)row / pixelHeight);// Possibly cancel.cancelToken.ThrowIfCancellationRequested();for (int col = 0; col < pixelWidth; col++){double x = center.Real - size.Width / 2 + col * size.Width / pixelWidth;Complex c = new Complex(x, y);Complex z = 0;int iteration = 0;bool isMandelbrotSet = false;if ((c - new Complex(-1, 0)).MagnitudeSquared < 1.0 / 16){isMandelbrotSet = true;}// http://www.reenigne.org/blog/algorithm-for-mandelbrot-cardioid/else if (c.MagnitudeSquared * (8 * c.MagnitudeSquared - 3) < 3.0 / 32 - c.Real){isMandelbrotSet = true;}else{do{z = z * z + c;iteration++;}while (iteration < iterations && z.MagnitudeSquared < 4);isMandelbrotSet = iteration == iterations;}bmpMaker.SetPixel(row, col, isMandelbrotSet ? Color.Black : Color.White);}}return bmpMaker;}, cancelToken);}
}

CancellationToken也作为第二个参数传递给Task.Run。 这不是必需的,但它允许Task.Run方法在已经请求取消甚至开始之前跳过大量工作。
另请注意,该代码现在跳过大型心形指针。 注释引用一个网页,该网页会在您想要检查数学的情况下派生公式。

第二十章:异步和文件I/O.(十九) 1相关推荐

  1. 通配符 不是jpg 结尾文件_Struts(十九)- 使用使用通配符匹配

    学习到目前为止,add,show, list分别需要进行配置 通过通配符匹配可以把这3个配置整合在一个配置中实现 步骤1:先运行,看到效果,再学习步骤2:模仿和排错步骤3:struts.xml步骤4: ...

  2. 网络知识入门,Web服务器的CGI程序,浏览器如何判断响应内容:文本,图片还是音频文件?(十九)

    目录 将请求的uri转换为实际的文件名 运行CGI程序 web服务器的访问控制 浏览器接受响应并返回内容 浏览器接受响应消息后如何显示内容 浏览器显示网页内容:访问完成 将请求的uri转换为实际的文件 ...

  3. python第二十九课——文件读写(复制文件)

    自定义函数:实现文件复制操作有形参(2个) 没有返回值相似版(不用) def copyFile(src,dest):#1.打开两个文件:1个关联读操作,1个关联写操作fr=open(src,'rb') ...

  4. 鸟哥的Linux私房菜(服务器)- 第二十章、WWW 伺服器

    第二十章.WWW 伺服器 最近更新日期:2011/08/05 我們最常講的『架站』其實就是架設一個 Web 網站啦!那麼什麼是 Web 呢?那就是全球資訊廣播的意思 (World Wide Web), ...

  5. 鸟哥的Linux私房菜(基础篇)- 第二十章、启动流程、模块管理与 Loader

    第二十章.启动流程.模块管理与 Loader 最近升级日期:2009/09/14 系统启动其实是一项非常复杂的程序,因为核心得要侦测硬件并加载适当的驱动程序后,接下来则必须要呼叫程序来准备好系统运行的 ...

  6. 【正点原子FPGA连载】 第二十章 LCD触摸屏实验摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

    1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: h ...

  7. 【正点原子MP157连载】第二十章 字符设备驱动开发-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  8. 【正点原子FPGA连载】 第二十章 LCD触摸屏实验 -摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0

    1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下 ...

  9. 第二十章 我国农村土地管理

    农村改革解说(专著)第二十章上 第二十章 我国农村土地管理上 1.为什么进行农村土地管理? 农村土地管理,就是对农村的集体所有制的土地进行管理.它不仅包括对现有耕地的管理,而且还包括对草原.山地.林地 ...

  10. 达芬奇密码 第二十章

    达芬奇密码 第二十章[@more@] 第二十章 兰登和索菲从阴影中走了出来,蹑手蹑脚地沿着空荡荡的艺术大画廊向紧急楼梯通道走去. 兰登边走边觉得自己好像在做一个智力游戏.眼前的问题很棘手:司法局长要给 ...

最新文章

  1. java web开发周志_javaweb学习笔记及周报告
  2. 通过padding-bottom或者padding-top实现等比缩放响应式图片
  3. javaPNS进阶-高级推送技巧
  4. oracle增加字段为主键自增_在 Oracle 中设置自增列
  5. 2017.10.9 DZY Loves Math V 失败总结
  6. 阿里巴巴在ITU-T成功立项数据安全相关标准
  7. kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能
  8. mysql的简单实用_MySQL的简单实用 手把手教学
  9. php联合查询的前提条件,PHP生成HTML前提条件及原理介绍_PHP教程
  10. 登录linux系统设置默认目录
  11. 计算机启动windows程序,win7系统开机自动运行程序怎么设置|win7电脑开机启动程序的方法...
  12. Delphi 跨语言环境 乱码问题
  13. 1125 Chain the Ropes
  14. 涨知识了,您想知道的光纤常识都在这里了,太详细了,赶紧收藏吧
  15. 曼达洛人对机器人的评价_我们请来了五位星战粉,来一起听听他们对于《曼达洛人》第一季的感想吧...
  16. 时间煮雨,人生浅笑嫣然
  17. Android-Rxjava 常用操作符
  18. 幼儿园案例经验迁移_多种形式培养幼儿的迁移讲述能力
  19. SpringBoot集成Redis
  20. UnityUI超简单实现敌方血条近大远小的效果

热门文章

  1. mysql 将米换算公里_千米和公里怎么换算
  2. Hyperion Research:2021年量子计算市场收入已达4.9亿美元
  3. 北邮邮箱与Win10自带邮箱相连接
  4. 文因互联CEO鲍捷:八一八聊天机器人
  5. 常见蛋白质种类_常见的蛋白质食物有哪些
  6. UCML Ajax++框架介绍
  7. 计算机专业前端实习生的实习经历
  8. jQuery css选择器大全,总有你用得到的东西。
  9. web服务器创建站点,服务器:如何使用IIS建立网站
  10. 大数据的特点和快的原因