2019-9-2-C#同步方法转异步
title | author | date | CreateTime | categories |
---|---|---|---|---|
C#同步方法转异步
|
lindexi
|
2019-09-02 12:57:37 +0800
|
2018-2-13 17:23:3 +0800
|
C#
|
本文来告诉大家如何把同步的代码转换为异步
创建新线程
最简单的方法是创建一个新的线程,创建的方法是使用 Task.Run ,请看下面代码,原来有一个函数 Delay 需要把他转换为异步,就可以使用 DelayAsync 里面用一个线程
public async Task DelayAsync()
{ await Task.Run(()=>Delay());
} private void Delay()
{ }
AMP 转 EAP
在很古老的开发,微软告诉大家使用 AMP 异步编程模型 Asynchronous Programming Model,这个模型就是使用 Begin xx 和 End xx 的方法 如 FileStream.BeginRead 和Stream.EndRead 表示
现在微软告诉大家,建议使用 EAP 基于事件的异步模式,也就是 Async 的模型
例如有一个文件读取,文件读取可以使用 BeginRead 和 EndRead ,看到下面代码大家就会觉得这很难用
var fileStream = new FileStream("E:\\lindexi\\博客",FileMode.Open); var buffer =new byte[65535];
IAsyncResult asyncResult=null;
fileStream.BeginRead(buffer, 0, buffer.Length, ar => { asyncResult = ar;}, null); fileStream.EndRead(asyncResult);
好在微软提供一个方式把上面的代码转换为 async ,方法是 Task.Factory.FromAsync 请看代码
await Task.Factory.FromAsync(fileStream.BeginRead, fileStream.EndRead, buffer, 0, buffer.Length, null);
如果希望对于如动画的等待,那么建议看如何实现一个可以用 await 异步等待的 Awaiter - walterlv
从如何实现一个可以用 await 异步等待的 Awaiter - walterlv复制出来类 DispatcherAsyncOperation
动画的等待是在动画结束返回函数,也许这里比较难说,动画有开始和结束事件,希望在结束事件函数才返回
private void TrirlelJallardra()
{
// 执行动画
TeedraiseTeretal(); // 期望在动画结束才做的代码 } /// <summary>
/// 执行动画
/// </summary>
private void TeedraiseTeretal()
{
var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回
};
}
因为 TrirlelJallardra 拿不到 storyboard.Completed 所以如果要在动画完成之后写调用代码是很难的。
为什么需要在其他函数写?如果是继续执行动画,而且需要在上一个动画执行完成,写在 Completed 的代码会很多。如果可以使用下面的函数的方法,可读性比较好
private void TrirlelJallardra()
{
// 执行动画
Animation1(); // 期望在动画1完成继续动画2
Animation2(); // 在上一个动画完成才调用下一个动画 Animation3(); } /// <summary>
/// 执行动画1
/// </summary>
private void Animation1()
{
var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回
};
} /// <summary>
/// 执行动画2
/// </summary>
private void Animation2()
{
var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回
};
} /// <summary>
/// 执行动画3
/// </summary>
private void Animation3()
{
var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回
};
}
如果需要写在回调里,那么可读性比较差
private void TrirlelJallardra()
{
// 执行动画
Animation1();
} /// <summary>
/// 执行动画1
/// </summary>
private void Animation1()
{
var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回 // 期望在动画1完成继续动画2
Animation2(); };
} /// <summary>
/// 执行动画2
/// </summary>
private void Animation2()
{
var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回 // 在上一个动画完成才调用下一个动画 Animation3();
};
} /// <summary>
/// 执行动画3
/// </summary>
private void Animation3()
{
var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回
};
}
那么这时使用 DispatcherAsyncOperation 就可以做异步,让代码可读性比上面好
private async void TrirlelJallardraAsync()
{
// 执行动画
await Animation1(); // 期望在动画1完成继续动画2
await Animation2(); // 在上一个动画完成才调用下一个动画 await Animation3();
} /// <summary>
/// 执行动画1
/// </summary>
private DispatcherAsyncOperation<bool> Animation1()
{
var dispatcherAsyncOperation = DispatcherAsyncOperation<bool>.Create(out var action); var storyboard = new Storyboard(); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) =>
{
// 这时函数才返回
action(true, null);
}; return dispatcherAsyncOperation;
} /// <summary>
/// 执行动画2
/// </summary>
private DispatcherAsyncOperation<bool> Animation2()
{
var storyboard = new Storyboard(); var dispatcherAsyncOperation = DispatcherAsyncOperation<bool>.Create(out var action); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) => { action(true, null); }; return dispatcherAsyncOperation;
} /// <summary>
/// 执行动画3
/// </summary>
private DispatcherAsyncOperation<bool> Animation3()
{
var storyboard = new Storyboard(); var dispatcherAsyncOperation = DispatcherAsyncOperation<bool>.Create(out var action); //设置动画 storyboard.Begin(this); storyboard.Completed += (sender, args) => { action(true, null); }; return dispatcherAsyncOperation;
}
2019-9-2-C#同步方法转异步的更多相关文章
- C#同步方法转异步
public async Task DelayAsync() { await Task.Run(()=>Delay()); } private void Delay() { } 本作品采用知识共 ...
- Task异步编程
Task异步编程中,可以实现在等待耗时任务的同时,执行不依赖于该耗时任务结果的其他同步任务,提高效率. 1.Task异步编程方法签名及返回值: a) 签名有async 修饰符 b) 方法名以 Asyn ...
- C# 异步和委托学习
IAsyncResult是接口: IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来实现原同步方法的异步调用,如 ...
- 同步方法、同步代码块、volidate变量的使用
当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线程改过了. ...
- C#中的异步调用及异步设计模式(二)——基于 IAsyncResult 的异步设计模式
三.基于 IAsyncResult 的异步设计模式(设计层面) IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来 ...
- 利用tornado使请求实现异步非阻塞
基本IO模型 网上搜了很多关于同步异步,阻塞非阻塞的说法,理解还是不能很透彻,有必要买书看下. 参考:使用异步 I/O 大大提高应用程序的性能 怎样理解阻塞非阻塞与同步异步的区别? 同步和异步:主要关 ...
- C#异步编程模式IAsyncResult
IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来实现原同步方法的异步调用,如 FileStream 类提供了 B ...
- win10 uwp 异步转同步
原文:win10 uwp 异步转同步 有很多方法都是异步,那么如何从异步转到同步? 可以使用的方法需要获得是否有返回值,返回值是否需要. 如果需要返回值,使用GetResults 如从文件夹获取文件: ...
- .NET中的异步编程——常见的错误和最佳实践
在这篇文章中,我们将通过使用异步编程的一些最常见的错误来给你们一些参考. 背景 在之前的文章<.NET中的异步编程——动机和单元测试>中,我们开始分析.NET世界中的异步编程.在那篇文章中 ...
随机推荐
- 浅谈Android开机启动速度优化(含应用程序启动速度优化)
众所周知Android开机启动速度较慢,于是如何加快启动速度便成为一个值得讨论的问题. 在查阅过许多资料后(特别是Google Group的android-platform),我整理总结出下面几点基本 ...
- 【转载】Jmeter之Bean shell使用(二)
Jmeter之Bean shell使用(二) 原博文地址为:https://www.cnblogs.com/puresoul/p/4949889.html 其中需要注意的是——三.自定义函数中Bean ...
- jmeter的关联-正则表达式的应用
LoadRunnner中的关联为web_reg_save_param,查找左右边界,下次请求的时候会用到上次请求服务器返回的数据,那么我们把符合左右边界的数据保存下来,以便下次请求的时候用到. jme ...
- iOS 9 学习系列:UIStack View
http://www.cocoachina.com/ios/20150921/13492.html 在 iOS9 中,Apple 引入了 UIStackView,他让你的应用可以通过简单的方式,纵向或 ...
- Cmakelists.txt中配置glfw
qt中需要用cmake编译工程,且需要用到OpenGL库glfw,如何给Cmakelist.txt配置glfw的动态链接库? 在Cmakelists.txt添: find_package(glfw3 ...
- Person Re-identification 系列论文笔记(二):A Discriminatively Learned CNN Embedding for Person Re-identification
A Discriminatively Learned CNN Embedding for Person Re-identification Zheng Z, Zheng L, Yang Y. A Di ...
- UVa 926【简单dp,递推】
UVa 926 题意:给定N*N的街道图和起始点,有些街道不能走,问从起点到终点有多少种走法. 很基础的dp.递推,但是有两个地方需要注意,在标记当前点某个方向不能走时,也要同时标记对应方向上的对应点 ...
- jmeter响应代码为乱码
1.在请求的前面添加BeanShell PostProcessor 输入prev.setDataEncoding("UTF-8"); 2.当响应数据或响应页面没有设置编码时,jme ...
- Linux中使用gcc编译文件
一个项目中可能有多个cpp文件,在linux下编译执行过程如下: g++ main.cpp distance.cpp ./a.out 即可一起编译两个文件,然后执行该程序.
- TAE words
love handle pang carbohydrate podiatry splay out Cinderella liposuction mingle fly t ...