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世界中的异步编程.在那篇文章中 ...
随机推荐
- CMake学习笔记六-引用cmake文件
include(${CMAKE_CURRENT_SOURCE_DIR}/../Share/share.cmake)
- 实现手机网页调起原生微信朋友圈分享的工具nativeShare.js
http://www.liaoxiansheng.cn/?p=294 我们知道现在我们无法直接通过js直接跳转到微信和QQ等软件进行分享,但是现在像UC浏览器和QQ浏览器这样的主流浏览器自带一个分享工 ...
- 【JZOJ4925】【GDOI2017模拟12.18】稻草人
题目描述 YLOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,YLOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条 ...
- PHPCMS快速建站系列之常用标签
<span class="Nmore"><a href="/index.php?m=content&c=index&a=lists&am ...
- 洛谷 P3768 简单的数学题 (莫比乌斯反演)
题意:求$(\sum_{i=1}^{n}\sum_{j=1}^{n}ijgcd(i,j))mod p$(p为质数,n<=1e10) 很显然,推式子. $\sum_{i=1}^{n}\sum_{j ...
- python 文本文件的写入
- mysql字段中提取汉字,去除数字以及字母
如果只是删除尾部的中文,保留数据,可以用以下的简单方式 MySQL as num; +------+ | num | +------+ | +------+ DELIMITER $$ DROP FUN ...
- Java练习 SDUT-1132_斐波那契数列
C/C++经典程序训练2---斐波那契数列 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 编写计算斐波那契(Fibon ...
- windows 和 linux 安装 tensorflow
安装 跟往常一样,我们用 Conda 来安装 TensorFlow.你也许已经有了一个 TensorFlow 环境,但要确保你安装了所有必要的包. OS X 或 Linux 运行下列命令来配置开发环境 ...
- C运行时库函数
C运行时库函数是指C语言本省支持的一些基本函数,通常是汇编直接实现的. API函数是操作系统提供给用户方便设计应用程序的函数,实现一些特定的功能,API函数也是C语言的函数实现的. 他们之间区别是: ...