更新记录

本文迁移自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中如何在同步代码块中调用异步方法的更多相关文章

  1. wait、notify为什么要放在同步代码块中

    等待方遵循的原则: 获取对象的锁,不满足条件就调用wait()方法,条件满足继续执行 通知方原则: 获取对象的锁,改变条件,然后notify 每个对象都有一个监视器锁,这个监视器锁的数据结构如下: w ...

  2. java中的synchronized同步代码块和同步方法的区别

    下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...

  3. java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

    在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity.所有对象的非同步方法都能够在任意时刻被任意线程调用 ...

  4. [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

    在 Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...

  5. 【面试普通人VS高手系列】讲一下wait和notify这个为什么要在synchronized代码块中?

    一个工作七年的小伙伴,竟然不知道"wait"和"notify"为什么要在Synchronized代码块里面. 好吧,如果屏幕前的你也不知道,请在评论区打上&qu ...

  6. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

  7. JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this

    JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程 ...

  8. 同步方法、同步代码块、volidate变量的使用

    当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线程改过了. ...

  9. java 同步代码块与同步方法

    同步代码块 synchronized (obj) { // 代码块 } obj 为同步监视器,以上代码的含义为:线程开始执行同步代码块(中的代码)之前,必须先获得对同步监视器的锁定. 代码块中的代码是 ...

随机推荐

  1. Kubernetes 解决方案-图解

  2. 查看k8s的yaml里面反馈的错误,不仅仅是通过日志来查看错误

    使用:kubectl describe pod......例如: kubectl describe pod api-55f5d8d49d-kzmcj ///////////////////////// ...

  3. ansble通过脚本定时清理k8s日志

    环境:环境k8s1.17,ansble通过脚本定时清理k8s日志 [root@tidb-21 delete-k8s-logs]# lsansib-delete.sh delete-logs.sh [r ...

  4. Hyperledger Fabric无排序组织以Raft共识算法启动多个Orderer服务、多组织共同运行维护Orderer服务

    前言 在Hyperledger Fabric无系统通道启动及通道的创建和删除中,我们已经完成了以无系统通道的方式启动 Hyperledger Fabric 网络,并将链码安装到指定通道.但目前为止,实 ...

  5. HCNP Routing&Switching之组播技术PIM-SM 稀疏模式

    前文我们了解了组播路由协议PIM以及PIM-DM密集模式相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16084310.html:今天我们来聊一聊PI ...

  6. 2021.08.16 P1363 幻象迷宫(dfs,我感受到了出题人浓浓的恶意)

    2021.08.16 P1363 幻象迷宫(dfs,我感受到了出题人浓浓的恶意) P1363 幻象迷宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 幻象迷宫可以认为是无限 ...

  7. GeoServer style中文乱码解决方法

    在说明这个问题之前,有三点需要明确: 一是创建New style时,网页中文本框内的内容才是最终会应用到GeoServer的sld内容,这与本地sld文件没有关系. 二是xml的encoding定义的 ...

  8. Java基础语法Day_02-03(数据类型、运算符、方法、循环结构)

    第5节 数据类型转换 day02_01_数据类型转换_自动转换 day02_02_数据类型转换_强制转换 day02_03_数据类型转换_注意事项 day02_04_ASCII编码表 第6节 运算符 ...

  9. 从0开始用webpack开发antd,react组件库npm包并发布

    一.初始化一个npm包 1.新建一个文件夹(名称随意,建议和报名一致),输入命令 :npm init -y 会自动生成一个包的说明文件 package.json如下(本文以scroll-antd-ta ...

  10. SDDC的Windows初体验-QT篇

    前言 如果熟悉爱智和看过我之前文章的朋友见到这篇文章一定会有很大疑问,SDDC 作为智能设备发现控制协议,怎么会用在 windows 上? 这一切还是源自于我巨大的脑洞,因为这段在搞 Windows ...