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世界中的异步编程.在那篇文章中 ...
随机推荐
- Spark day02
Standalone模式两种提交任务方式 Standalone-client提交任务方式 提交命令 ./spark-submit --master spark://node1:7077 --class ...
- 2019.10.22 用TCP实现服务端并发接收
client import socket client = socket.socket() client.connect( ('127.0.0.1',8888) ) while 1: msg = in ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十九章:法线贴图
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十九章:法线贴图 学习目标 理解为什么需要法线贴图: 学习法线贴图如 ...
- python 对象的封装性
- 2017校赛 C: 不爱学习的小W【模拟】
题目描述 “叮铃铃”上课了,同学们都及时到了教室坐到了座位上,教室里有n行m列的座位而且刚好坐满.既然是上课,那老师叫学生回答问题就是再正常不过的事了,同样地,教室里也就有爱学习和不爱学习的学生了,爱 ...
- Python学习之路15☞socket编程
一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二 os ...
- 【Linux】 经典Linux系统工程师面试题(转载)
1.如何将本地80端口的请求转发到8080端口,当前主机IP为192.168.16.1,其中本地网卡eth0: 答: # iptables -t nat -A PREROUTING -d 192.16 ...
- javascript中字符的一些常规操作
1,获取第一个字符 var str = "hello word"; console.log(str[0]); // h 2,获取最后一个字符 var str = "hel ...
- vue页面内监听路由变化
beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当钩子执行前,组件实 ...
- python == 符号