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世界中的异步编程.在那篇文章中 ...
随机推荐
- Servlet各种接口和类
http://blog.csdn.net/jediael_lu/article/details/25036019
- Mybatis中example类的使用
要使用example类,先要在项目中导入mybatis.mapper的jar包. Mapper接口中包含了单表的增删改查以及分页功能. 给出实例: CountryMappermapper = sqlS ...
- Directx11教程39 纹理映射(9)
原文:Directx11教程39 纹理映射(9) 在myTutorialD3D11_32中,我们在PlaneModelClass中增加一个纹理TextureClass* m_Texture;读 ...
- day39-Spring 14-Spring的JDBC模板:DBCP连接池配置
一般常用的连接池是DBCP和C3P0. package cn.itcast.spring3.demo1; import java.sql.DriverManager; import org.junit ...
- day4_python-之装饰器、迭代器、生成器
一.装饰器 1.为何要用装饰器 #开放封闭原则:对修改封闭,对扩展开放 2. 什么是装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被 ...
- MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数
MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数 计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数,这里主要分享的是通过MySql内置的函数 TimeStampDiff() ...
- TreeSet的运用之使用内部比较器实现自定义有序(重要)
Student.java package com.sxt.set3; /* * TreeSet:有序 * implements Comparable<Student> * 如果用内部比较器 ...
- iOS之友盟错误统计解决
http://www.cocoachina.com/ios/20150720/12627.html http://lieyunye.github.io/blog/2013/09/10/how-to-a ...
- Flask学习之四 数据库
英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-iv-database 中文翻译地址:http://ww ...
- Python字节码介绍
了解 Python 字节码是什么,Python 如何使用它来执行你的代码,以及知道它是如何帮到你的.如果你曾经编写过 Python,或者只是使用过 Python,你或许经常会看到 Python 源代码 ...