更新记录

本文迁移自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. spring-bean依赖注入-03

    set注入:set注入地址 通过构造方法进行注入 1.创建UserDao接口以及UserDaoImpl实现类(接口代码省略) public class UserDaoImpl implements U ...

  2. php进制转换

    前端html页面代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  3. TemplatesImpl利用链

    FastJson利用链 Fastjson的版本在1.2.22-1.2.24主要有两条链利用TemplatsImpl和JdbcRowSetImpl利用链先来学习TemplatsImpl利用链,这个与前面 ...

  4. Java语言学习day14--7月19日

    ###10数组逆序功能实现 * A:案例代码 /* 数组的逆序: 数组中的元素,进行位置上的交换 逆序 不等于 反向遍历 就是数组中最远的两个索引,进行位置交换,实现数组的逆序 使用的是数组的指针思想 ...

  5. Book2Notion:将豆瓣图书信息同步到Notion的Chrome插件

    背景 前几天写了一个python脚本从豆瓣爬数据然后保存到Notion,被身边同学吐槽使用起来太麻烦,而且也不是所有人都会Python(原话是充满了码农版"何不食肉糜").正好最近 ...

  6. C# 11 的这个新特性,我愿称之最强!

    前言 在日常开发中我们经常会将JSON.XML.HTML.SQL.Regex等字符串拷贝粘贴到我们的代码中,而这些字符串往往包含很多的引号",我们就必须将所有引号逐个添加转义符\进行转义.这 ...

  7. React 父组件调用子组件的方法

    父组件调用子组件的方法 React v16.3.0 及以后版本使用 import React, {Component} from 'react'; export default class Paren ...

  8. Halo 开源项目学习(四):发布文章与页面

    基本介绍 博客最基本的功能就是让作者能够自由发布自己的文章,分享自己观点,记录学习的过程.Halo 为用户提供了发布文章和展示自定义页面的功能,下面我们分析一下这些功能的实现过程. 管理员发布文章 H ...

  9. 干货长文:Linux 文件系统与持久性内存介绍

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 1.Linux 虚拟文件系统介绍 在 Linux 系统中一切皆文件,除了通常所说的狭义的文件以 ...

  10. CSAPP 之 DataLab 详解

    前言 本篇博客将会剖析 CSAPP - DataLab 各个习题的解题过程,加深对 int.unsigned.float 这几种数据类型的计算机表示方式的理解. DataLab 中包含下表所示的 12 ...