.NET中如何在同步代码块中调用异步方法
更新记录
本文迁移自Panda666原博客,原发布时间:2021年7月2日。
在同步代码块中调用异步方法,方法有很多。
一、对于有返回值的Task
在同步代码块中直接访问 Task 的 Result 属性,这会阻塞调用线程直到返回Result为止。
代码实例:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace PandaTestClass
{
class Program
{
private static async Task<(string, string)> DoSomething()
{
//用于返回值
(string, string) result = ("?", "?");
//任务1
await Task.Run(() => {
//模拟耗时任务
for (int i = 0; i <= 100; i += 20)
{
Console.WriteLine($"任务1,当前执行到:{i}%");
Thread.Sleep(TimeSpan.FromSeconds(1));
}
//写入返回值
result.Item1 = "任务1完成";
});
//任务2
await Task.Run(() => {
//模拟耗时任务
for (int i = 0; i <= 100; i += 20)
{
Console.WriteLine($"任务2,当前执行到:{i}%");
Thread.Sleep(TimeSpan.FromSeconds(1));
}
//写入返回值
result.Item2 = "任务2完成";
});
//确保任务执行完成
Task.WaitAll(new Task[] { });
//返回返回值
return result;
}
static void Main(string[] args)
{
//同步块中使用异步方法
//这里会阻塞主线程
(string t1, string t2) result = DoSomething().Result;
//执行完成
Console.WriteLine("DoSomething Success");
//获得结果集1
Console.WriteLine(result.t1);
//获得结果集2
Console.WriteLine(result.t2);
//wait
Console.WriteLine("Main Suceess");
Console.ReadKey();
}
}
}
二、使用Task.Run()方法包裹
强烈推荐该方法。
代码实例:
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace PandaTestClass
{
class Program
{
/// <summary>
/// 异步方法
/// </summary>
/// <returns></returns>
private static async Task<(string, string)> DoSomething()
{
//用于返回值
(string, string) result = ("?", "?");
//任务1
await Task.Run(() => {
//模拟耗时任务
for (int i = 0; i <= 100; i += 20)
{
Console.WriteLine($"任务1,当前执行到:{i}%");
Thread.Sleep(TimeSpan.FromSeconds(1));
}
//写入返回值
result.Item1 = "任务1完成";
});
//任务2
await Task.Run(() => {
//模拟耗时任务
for (int i = 0; i <= 100; i += 20)
{
Console.WriteLine($"任务2,当前执行到:{i}%");
Thread.Sleep(TimeSpan.FromSeconds(1));
}
//写入返回值
result.Item2 = "任务2完成";
});
//确保任务执行完成
Task.WaitAll(new Task[] { });
//返回返回值
return result;
}
static void Main(string[] args)
{
//同步块中使用异步方法
//这里会阻塞主线程
Task<(string t1, string t2)> returnValue = Task.Run(async () => {
(string t1, string t2) r = await DoSomething();
return r;
});
//执行完成
//获得结果集1
Console.WriteLine(returnValue.Result.t1);
//获得结果集2
Console.WriteLine(returnValue.Result.t2);
//wait
Console.WriteLine("Main Suceess");
Console.ReadKey();
}
}
}
.NET中如何在同步代码块中调用异步方法的更多相关文章
- wait、notify为什么要放在同步代码块中
等待方遵循的原则: 获取对象的锁,不满足条件就调用wait()方法,条件满足继续执行 通知方原则: 获取对象的锁,改变条件,然后notify 每个对象都有一个监视器锁,这个监视器锁的数据结构如下: w ...
- java中的synchronized同步代码块和同步方法的区别
下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity.所有对象的非同步方法都能够在任意时刻被任意线程调用 ...
- [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在 Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...
- 【面试普通人VS高手系列】讲一下wait和notify这个为什么要在synchronized代码块中?
一个工作七年的小伙伴,竟然不知道"wait"和"notify"为什么要在Synchronized代码块里面. 好吧,如果屏幕前的你也不知道,请在评论区打上&qu ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this
JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程 ...
- 同步方法、同步代码块、volidate变量的使用
当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线程改过了. ...
- java 同步代码块与同步方法
同步代码块 synchronized (obj) { // 代码块 } obj 为同步监视器,以上代码的含义为:线程开始执行同步代码块(中的代码)之前,必须先获得对同步监视器的锁定. 代码块中的代码是 ...
随机推荐
- Spring Boot-自动配置之底层原理
一.SpringBoot启动的时候加载主配置类,开启了自动配置的功能 @SpringBootApplication public class SpringBoot02Application { pub ...
- java数组算法——数组元素的赋值2
java数组算法--数组元素的赋值2--java经典面试题:创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值.同时要求元素时的值各不相同
- vue--vuex 状态管理模式
前言 vuex作为vue的核心插件,同时在开发中也是必不可少的基础模块,本文来总结一下相关知识点. 正文 1.基于单向数据流问题而产生了Vuex 单向数据流是vue 中父子组件的核心概念,props ...
- OpenHarmony 3.1 Release版本发布
OpenHarmony 3.1 Release 版本概述 当前版本在OpenHarmony 3.1 Beta的基础上,更新支持以下能力: 标准系统基础能力增强 本地基础音视频播放能力.视频硬编解码.相 ...
- Python工程打包
Python项目打包 我是自己写了一个项目,然后需要打包成问一个exe文件,这样直接打开这个文件就可以运行,而不需要在pycharm中打开相应文件才能运行,也可以将打包好的文件发给其他人,不需要pyc ...
- 如何突破Jenkins瓶颈,实现集中管理、灵活高效的CI/CD
在过去的几年间,随着DevOps的兴起,持续集成(Continuous Integration)与持续交付(Continuous Delivery)的热度也水涨船高.在本文中,我们将首先带您了解热门的 ...
- 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)
1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...
- 如何对用户的绑定的身份证真实性进行实名认证(java)
现在随着对用户实名制的要求,因此用户提交的身份证信息经查需要检查是否为真实信息,我们需要对用户提交的身份证信息进行核验,具体操作步骤如下: 第一步 到认证平台注册账号:云亿互通--实名认证服务 (yu ...
- C++实现矩阵类和向量类
C++期末作业内容,写完之后觉得过于臃肿,又重新搞了个新的.新的当作业交,旧的拿来给同学参考. [问题描述]请仿照复数类,设计一个矩阵类,设计矩阵类的构成元素 1.编写构造函数完成初始化 2.编写成员 ...
- 【译】defer-panic-and-recover
Go 有通用的控制流程:if,for,switch,goto.它也有go语句用于让代码运行在单独的协程.这里我将讨论一些不常见的问题:defer,panic 和 recover. defer语句将函数 ...