Nguyên tắc không đồng điệu (Asynchronous Principle )

Hãy tưởng tượng chúng ta chuẩn bị một bữa tiệc sáng gồm:

Pha 1 tách bóc cà phê
Rán ốp la 2 trái trứng
Nướng bánh mì

Thực hiện một giải pháp tuần tự hay theo nguyên tắc đồng bộ (Synchronous Principle) chúng ta sẽ pha tách cà phê (pha phin) với chờ quy trình này trả tất. Sau đó, bọn họ tiếp tục rán ốp la 2 quả trứng với chờ xong việc rán ốp la. ở đầu cuối là bọn họ sẽ nướng bánh mì. Trong khi nướng bánh mì chấm dứt tức là bữa sớm đã sẵn sàng. Bữa sớm trong tuần thường thời hạn hạn chế và nếu vận dụng cách làm tuần trường đoản cú như trên đang tiêu tốn rất nhiều thời gian và các món như ốp la sẽ bị nguội trong thời hạn chờ bánh mỳ sẽ làm bữa sớm mất hương vị.

Bạn đang xem: Cách dùng async trong c#

Trong thực tế, bao hàm việc chuẩn bị một bữa sáng dễ dàng như trên, họ không thực hiện quá trình một bí quyết tuần trường đoản cú như vậy. Hoàn toàn có thể trong thời hạn chờ cà phê chúng ta sẽ tranh thủ hơ nóng chảo cùng trong thời hạn đang hơ chảo chúng ta có thể nướng bánh mì. Trong thời gian bánh mì đang được nướng, bạn có thể đập nhì quả trứng và cho vô chảo đã nóng cùng quay quý phái kiểm tra bánh mỳ đang nướng… Các các bước đan xen nhau thay vì chưng tuần tự như trên dựa vào nguyên tắc ko tuần tự hay không đồng điệu (Asynchronous Principle).

Chúng ta có thể thực hiện nay các công việc hằng ngày theo cách không đồng hóa nhưng máy tính xách tay thì lại khác. Những lệnh trong một chương trình laptop được thực hiện một cách tuần tự buộc phải sẽ tốn rất nhiều thời gian. Trường hợp muốn máy tính thực hiện công việc theo cách không đồng bộ, bọn họ phải viết mã không đồng hóa (asynchronous code).

Mô hình lập trình không đồng bộ

C# hỗ trợ mô hình lập trình sẵn không đồng hóa (The Task Asynchronous Programming mã sản phẩm – TAP) góp việc triển khai mã không nhất quán một phương pháp hiệu quả. Các yếu tố chính trong quy mô TAP là lớp Task và những toán tử async cùng await.

Có không hề ít thông tin về Task, asyncawait hoàn toàn có thể tìm thấy dễ dàng trên Internet. Nội dung bài viết này không tập trung lý giải các khái niệm này mà lại sẽ minh họa qua 1 chương trình Console đơn giản. Lịch trình của bọn họ sẽ thực hiện công việc để chuẩn bị một bữa ăn sáng như sẽ nêu ví dụ sinh sống trên.

Chương trình chuẩn bị bữa ăn sáng

Mở Visual Studio phiên phiên bản từ 2017 trở lên, tạo nên một ứng dụng Console app (.NET Core) thương hiệu Bua
An
Sang
và lưu áp dụng tại một vị trí phù hợp. Tập tin Program.cs tất cả nội dung mặc định như sau:

using System;namespace Bua
An
Sang class Program static void Main(string<> args) Console.Write
Line("Hello World!"); Trong namespace Bua
An
Sang
thêm 3 lớp Trung, Banhmi với Caphe như sau:

using System;namespace Bua
An
Sang class Program static void Main(string<> args) Console.Write
Line("Hello World!"); internal class Banhmi internal class Caphe internal class Trung Bên vào lớp Program thêm những phương thức Pha_Caphe(), Ran_Trung_Opla() với Nuong_Banhmi() như sau:

using System;namespace Bua
An
Sang class Program static void Main(string<> args) Console.Write
Line("Hello World!"); private static Caphe Pha_Caphe() Console.Write
Line("Dang trộn ca phe..."); return new Caphe(); private static Trung Ran_Trung_Opla(int So_trung) Console.Write
Line("Ho nống chao..."); Task.Delay(3000).Wait(); Console.Write
Line($"Đap So_trung qua trung"); Console.Write
Line("Ran trung..."); Task.Delay(3000).Wait(); Console.Write
Line("Dat trung ra dia..."); return new Trung(); private static Banhmi Nuong_banhmi() Console.Write
Line("Dang nuong banh mi..."); Task.Delay(3000).Wait(); return new Banhmi(); internal class Banhmi internal class Caphe internal class Trung Phương thức Delay(3000).Wait() của lớp Task dùng để trì hoãn 3 giây trước khi triển khai lệnh kế tiếp. Trong hàm Main bọn chúng ta thay đổi như sau:

static void Main(string<> args) Caphe ly = Pha_Caphe(); Console.Write
Line("Ca phe san sang"); Trung dia = Ran_Trung_Opla(2); Console.Write
Line("Trung op la san sang"); Banhmi bm = Nuong_banhmi(); Console.Write
Line("Banh mi san sang"); Console.Write
Line("BUA sang HOAN TAT. XIN MOI!!!"); Console.Write("
Nhan phim bat ky de thoat..."); Console.Read
Key(true);Thực thi chương trình bữa tiệc sáng chúng ta sẽ có hiệu quả như sau:

*

Quan gần kề kết quả họ thấy chương trình triển khai một phương pháp tuần tự tốt đồng bộ các bước để sẵn sàng một bữa ăn sáng.

Chương trình không đồng nhất – Version 1

Chương trình Bua
An
Sang
triển khai các lệnh đồng điệu và muốn biến hóa sang triển khai không đồng bộ họ cần sử dụng mô hình TAP với lớp Task và các toán tử async với await. Một phiên phiên bản mới của hàm Main đang như sau:

static async Task Main(string<> args) Caphe ly = Pha_Caphe(); Console.Write
Line("Ca phe san sang"); Trung dia = await Ran_Trung_Opla(2); Console.Write
Line("Trung op la san sang"); Banhmi bm = await Nuong_banhmi(); Console.Write
Line("Banh ngươi san sang"); Console.Write
Line("BUA sang HOAN TAT. XIN MOI!!!"); Console.Write("
Nhan phim bat ky de thoat..."); Console.Read
Key(true);Chúng ta ý muốn rằng khi cách thức Pha_Caphe() đang tiến hành thì các phương thức Ran_Trung_Opla()Nuong_Banhmi() cũng có thể được thực hiện mà không trở nên khóa (block) vị CPU máy tính. Mong vậy, họ phải thực hiện các chuyển đổi sau:

– biến đổi phương thức Main thành phương thức xúc tiến không đồng điệu bằng cách:

static async Task Main(string<> args)Hàm Main không thể trả về void như khoác định nữa nhưng mà trả về quý giá kiểu Task. từ bỏ khóa async chứng thực phương thức Main thực hiện theo phương pháp không đồng bộ.

– lúc Main sử dụng từ khóa async, các lệnh bên trong có thể xúc tiến theo cơ chế không đồng bộ bằng phương pháp dùng từ bỏ khóa await trước các lệnh đó, ví dụ là hai cách tiến hành Ran_Trung_Opla() Nuong_Banhmi():

Trung dia = await Ran_Trung_Opla(2);Banhmi bm = await Nuong_banhmi();– Vì những phương thức Ran_Trung_Opla() với Nuong_Banhmi() triển khai theo vẻ ngoài không đồng điệu nên, giống như Main, chúng phải được khái niệm là đông đảo phương thức thi không đồng bộ:

private static async Task Ran_Trung_Opla(int So_trung) ... Await Task.Delay(3000); ... Await Task.Delay(3000); ... Return new Trung();private static async Task Nuong_banhmi() ... Await Task.Delay(3000); return new Banhmi();Như vậy họ đã tất cả một phiên phiên bản đơn giản của chương trình thực thi không đồng bộ. Thực hiện lệnh. Vì bọn họ thực hiện áp dụng trong Visual Studio 2017 nên rất có thể xảy ra lỗi như sau:

CS5001 Program does not contain a static "Main" method suitable for an entry point
Các phiên bản C# từ bỏ 7.0 trở về trước không được cho phép đánh dấu phương thức Main như là phương thức ko đồng bộ. Điều này chỉ áp dụng kể từ phiên bản C# 7.1 trờ về sau.

Để hạn chế lỗi, họ nhấn chuột đề nghị vào dự án công trình Bua
An
Sang
trong hành lang cửa số Solution Explorer, chọn Properties. Tại mục Build tìm đến nút Advanced:

*

Nhấn nút Advance. Vào Advanced Build Settings tại Language version lựa chọn phiên hải dương C# tự 7.1 trở lên cùng nhấn OK.

*

Đóng form Properties và tiến hành lại ứng dụng. Tác dụng thực thi

*

Với phiên phiên bản đơn giản của bọn họ thì những nhiệm vụ vẫn được triển khai tuần tự mặc dù các trách nhiệm như rán trứng tuyệt nướng bánh mì không xẩy ra block khi trách nhiệm pha coffe đang diễn ra.

Chương trình không đồng hóa với các nhiệm vụ chuyển động song tuy nhiên – Version 2

Trong Version 1, bọn họ đã tạo ra một phiên bạn dạng chương trình không nhất quán nhưng những nhiệm vụ vẫn tiến hành tuần tự. Vào phiên bản này (Version 2), bọn họ sẽ cải tiến lại đoạn mã trong cách làm Main cho phép các nhiệm vụ triển khai một cách tuy nhiên song như sau:

static async Task Main(string<> args) Caphe ly = Pha_Caphe(); Console.Write
Line("Ca phe san sang"); Task rantrung = Ran_Trung_Opla(2); Task nuongbmi = Nuong_banhmi(); Trung dia = await rantrung; Console.Write
Line("Trung op la san sang"); Banhmi bmi = await nuongbmi; Console.Write
Line("Banh mi san sang"); Console.Write
Line("BUA sang HOAN TAT. XIN MOI!!!"); Console.Write("
Nhan phim bat ky de thoat..."); Console.Read
Key(true);Điều độc đáo ở đấy là chúng ta bắt đầu tất cả các công việc cùng một lúc cùng lưu giữ công dụng trả về từ những phương thức Ran_Trung_Opla() và Nuong_banhmi() trong các đối tượng người dùng Task (rantrungnuongbmi). họ muốn xử lý tác dụng từ quá trình nào thì sẽ sử dụng toán tử await trước đối tượng Task tương ứng. Thực hiện lại ứng dụng, công dụng sẽ khác biệt:

*

Chúng ta thấy rằng, khi đã hơ lạnh chảo (công việc rán trứng) thì rất có thể tiến hành nướng bánh mì (công việc nướng bánh mì). Dứt thì trứng và bánh mì cùng chuẩn bị sẵn sàng cho một bữa sớm ngon miệng.

Chương trình không đồng điệu với các nhiệm vụ hoạt động song tuy nhiên – Version 3 (Cuối cùng)

Phiên bản 2 (Version 2) là bước cải tiến hiệu quả để chương trình chúng ta cũng có thể thực hiện những nhiệm vụ tuy nhiên song. Tuy nhiên, chúng ta vẫn tất cả thể đổi mới một không nhiều cho thủ tục Main như sau:

static async Task Main(string<> args) Caphe ly = Pha_Caphe(); Console.Write
Line("Ca phe san sang"); Task rantrung = Ran_Trung_Opla(2); Task nuongbmi = Nuong_banhmi(); await Task.When
All(rantrung,nuongbmi); Console.Write
Line("Trung op la san sang"); Console.Write
Line("Banh ngươi san sang"); Console.Write
Line("BUA sang HOAN TAT. XIN MOI!!!"); Console.Write("
Nhan phim bat ky de thoat..."); Console.Read
Key(true);Ở đây, thay vị dùng nhiều lệnh await:

Trung dia = await rantrung;Banhmi bmi = await nuongbmi;Chúng ta rất có thể dùng trong một lệnh với cách làm When
All
của lớp Task:

await Task.When
All(rantrung,nuongbmi);Tuy nhiên, khi họ await tất cả các công việc thì họ vẫn không biết quá trình nào dứt trước, các bước nào chấm dứt sau vày các công việc có thời hạn thực hiện là không giống nhau. Một cách xử lý vấn đề này là dùng cách thức When
Any
của lớp Task và phương thức Main của bọn họ cần cách tân lại như sau:

static async Task Main(string<> args) Caphe ly = Pha_Caphe(); Console.Write
Line("Ca phe san sang"); var rantrung = Ran_Trung_Opla(2); var nuongbmi = Nuong_banhmi(); var dscongviec = new danh mục rantrung, nuongbmi; while (dscongviec.Any()) Task hoanthanh = await Task.When
Any(dscongviec); if(hoanthanh == rantrung) Console.Write
Line("Trung op la san sang"); else if (hoanthanh == nuongbmi) Console.Write
Line("Banh mi san sang"); dscongviec.Remove(hoanthanh); Console.Write
Line("BUA sang trọng HOAN TAT. XIN MOI!!!"); Console.Write("
Nhan phim bat ky de thoat..."); Console.Read
Key(true);Chúng ta vẫn đặt tất cả các bước (rangtrung, nuongbmi) vào một danh sách công việc kiểu danh sách và đã await các công việc trong list này bằng phương thức When
Any
của lớp Task và khắc ghi bằng biến một biến đổi (hoanthanh). Với phương pháp này, bạn cũng có thể dễ dàng kiểm tra công việc nào xong trước, các bước nào hoàn thành sau. Khi toàn bộ các các bước hoàn thành, xóa biến lưu lại bằng cách thức Remove.

Xem thêm: Hướng Dẫn Cách Dùng Zalo Trên Ipad, Hướng Dẫn Xoay App Zalo Trên Ipad

Trước khi triển khai lại lịch trình và cũng chính là phiên bản cuối cùng, họ cần coi lại các namespace chúng ta đã sử dụng để bảo vệ chương trình thực thi:

using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;Thực thi ứng dụng và kết quả:

*

Ở đây công việc nướng bánh mì ra mắt nhanh rộng rán ốp la đề xuất sẽ xong xuôi trước.

Lời cuối

Trong nội dung bài viết này bọn họ đã mày mò một bí quyết cơ bạn dạng mô hình lập trình không đồng nhất của ngữ điệu C#. Một chú ý rằng, lớp Task và những toán tử await với async luôn đi thuộc nhau. Các công việc có thể được tổ chức triển khai và await một cách tác dụng với những phương thức When
All
giỏi When
Any
tự lớp Task.

Tìm phát âm về lập trình bất đồng bộ, sử dụng lớp Task để chạy task, mày mò từ khóa async với await - áp dụng bất đồng bộ


Lập trình bất nhất quán asynchronous

Từ .NET Framework 4.5 nó tiếp tế thư viện mang tên Task Parallel Library (TPL) - TPL góp lập trình chạy tuy vậy song (đa luồng) dễ dàng hơn. Vào C# đồng thời nó sản xuất hai từ khóa là async với await, đấy là hai từ khóa chính để áp dụng trong lập trình sự không tương đồng bộ.

Lập trình bất đồng điệu (asynchronous) là một cách thức mà khi call nó chạy ở chính sách nền (liên quan mang lại một tiến trình, task), trong những khi đó quy trình gọi nó không xẩy ra khóa - block. Trong .NET có tiến hành một số mô hình lập trình bất nhất quán như Asynchronous pattern, chủng loại bất nhất quán theo sự kiện cùng theo tác vụ (TAP - task-based asynchronous pattern)

Phần này sẽ nói tới TAP - task-based asynchronous pattern - chiêu mộ hình lập trình bất đồng hóa thông dụng bên trên .NET hiện nay nay.

Lập trình đồng nhất synchronous

Bình thường, khi lập trình gọi một cách thức nào kia thì cách làm đó chạy và kết thúc thì các dòng code tiếp theo sau sau lời gọi cách tiến hành đó new được thực thi, sẽ là chạy đồng bộ, tức là thread gọi cách thức bị khóa lại cho đến khi cách thức kết thúc.


Thử xem ví dụ đơn giản dễ dàng sau:

Download
Website01.cs

using System;using System.Net;using System.Threading;namespace CS021_ASYNCHRONOUS public class Download
Website01 public static string Download
Webpage (string url, bool showresult) using (var client = new Web
Client ()) Console.Write ("Starting tải về ..."); string nội dung = client.Download
String (url); Thread.Sleep (3000); if (showresult) Console.Write
Line (content.Substring (0, 150)); return content; public static void Test
Download
Webpage() string url = "https://code.visualstudio.com/"; Download
Webpage(url, true); Console.Write
Line("Do somthing ..."); Hãy call Test
Download
Webpage() trong hàm main nhằm kiểm tra.

Phương thức Download
Webpage sử dụng lớp Web
Client để download về một trang web, trả về chuỗi ngôn từ trang.

Khi chạy, thì lời gọi Download
Webpage(url, true);, thủ tục này thi hành xong thì dòng code
Console.Write
Line("Do somthing ..."); new được thi hành.

Vấn đề là lúc Download
Webpage(url, true); chạy, nó đang khóa thread call nó, làm cho các dòng code tiếp sau phải chờ, giả dụ hàm đó thi hành mất nhiều thời gian (đặc biệt là các thao tác đọc stream - gọi file, kết nối web, kết nối CSDL ...) - trong lúc tài nguyên vẫn đủ để triển khai các câu hỏi khác - thì chương trình vẫn cứ phải chờ phương thức trên xong thì new thi hành được tác vụ không giống - đặt biệt là lúc gọi phương thức trong các tiến trình UI, giao diện người dùng không liên can được.

Để giải quyết vấn đề này, trong những khi chờ cho Download
Webpage(url, true) thực hành xong, công tác vẫn thi hành được những tác vụ khác thì nên cần đến kỹ thuật lập trình bất đồng nhất (trước đây điện thoại tư vấn là lập trình nhiều tiến trình, đa luồng)

Lớp Task

Lớp Task nó bộc lộ tác vụ bất đồng bộ, từ kia ta chạy được code bất đồng bộ. Nếu tác vụ bất đồng điệu đó thi hành xong xuôi có mẫu mã trả về thì cần sử dụng Task với T là hình dạng trả về.

Cần sử dụng những namespace sau để sở hữu thư viện về Task

using System.Threading;using System.Threading.Tasks;Chú ý hãy khám phá về hàm ủy quyền delegate C# trước

Cú pháp chế tạo ra đối tượng người sử dụng Task cơ bản

Để tạo ra một Task bạn phải tham số là một hàm delegate ( Func hoặc Action), ví dụ delegate mang tên myfunc thìkhởi tạo

Nếu myfunc trả về kiểu T (tức là một trong Func) thì khởi tạo

Task task = new Task(myfunc); Nếu đề nghị truyền tham số cho myfunc thì khởi tạo:

// object là đối tượng người tiêu dùng tham số truyền cho myfunc
Task task = new Task(myfunc, object); nếu myfunc ko trả về giá trị (tức là Action) thì khởi tạo:

// object là đối tượng người sử dụng tham số truyền mang lại myfunc
Task task = new Task(myfunc); Để chạy Task gọi cách làm Start() của đối tượng được sản xuất ra. Nếucó hiệu quả trả về thì đọc kết quả tại trực thuộc tính Result, đề đợi cho task hoànthành thì điện thoại tư vấn Wait()

Ta sẽ có tác dụng một ví dụ sử dụng Task tạo ra các 2 quy trình con chạy đồng thời:

Test
Async01.cs

using System;using System.Net;using System.Threading;using System.Threading.Tasks;namespace CS021_ASYNCHRONOUS { public class Test
Async01 { // Viết ra screen thông báo bao gồm màu public static void Write
Line (string s, Console
Color color) Console.Foreground
Color = color; Console.Write
Line (s); // tạo nên và chạy Task, áp dụng delegate Func (có hình dáng trả về) public static Task Async1 (string thamso1, string thamso2) { // tạo biến hóa delegate trả về vẻ bên ngoài string, tất cả một tham số object Func myfunc = (object thamso) => // Đọc thông số (dùng kiểu đụng - xem kiểu cồn để biết đưa ra tiết) dynamic ts = thamso; for (int i = 1; i task = new Task (myfunc, new x = thamso1, y = thamso2 ); task.Start(); // chạy thread // Làm nào đó sau khi chạy Task tại chỗ này Console.Write
Line("Async1: Làm gì đó sau lúc task chạy"); return task; // sản xuất và chạy Task, thực hiện delegate kích hoạt (không phong cách trả về) public static Task Async2 () { action myaction = () => { for (int i = 1; i Chạy trong hàm main

Console.Write
Line($"" ",5 Thread.Current
Thread.Managed
Thread
Id,3 Main
Thread");Task t1 = Test
Async01.Async1("A", "B");Task t2 = Test
Async01.Async2();Console.Write
Line("Làm nào đó ở thread chính sau thời điểm 2 task chạy");// đợi t1 xong và đọc tác dụng trả vềt1.Wait();String s = t1.Result;Test
Async01.Write
Line(s, Console
Color.Red);// Ngăn quán triệt thread bao gồm kết thúc// nếu như thread chính hoàn thành mà t2 đang hoạt động nó có khả năng sẽ bị ngắt
Console.Read
Key();Kết quả chạy

*

Để khởi tạo nên một Task bạn cần tham số là 1 trong delegate (Func hoặc Action) - yêu cầu cần nắm vững về delegate Func cùng Action trước.

Lưu ý: áp dụng Task với Func : lúc khởi chế tạo một task yêu cầu tham sốlà một delegate, khi task chạy xong thì có công dụng trả về nên dùng cho delegate dạng Func,đầu tiên tạo Delegate dạng này với cú pháp như sau (trường phù hợp trong Async1 sinh hoạt trên)

Func func = (object thamso) => // code ... Return ...;;Sau đó chế tạo Task với cú pháp

Task task = new Task(func, thamso);Khi đã có Task, gọi cách tiến hành Start() của nó để bắt đầu chạy thread, một thread new bất nhất quán sẽkhởi chạy - nó sẽ không khóa thread hotline nó - những dòng code tiếp theo sau của thread bao gồm vẫn chạy trong khi Task đang thi hành.

Khi Task chạy xong, hiệu quả delegate trả về giữ ở nằm trong tính Result (task.Result)

Kết quả chạy code trên, nhì thread con đang làm việc song song, trong những lúc thread bao gồm đàng chờ fan người dùngbấm bàn phím.

Cũng lưu ý Async2 ở trên lại sử dụng Task chứ không phải Task, vận dụng khi hàm bất đồng nhất không cầnkết quả trả về, lúc này lại dùng hàm delegate dạng action chứ không cần sử dụng Func, cú pháp:

Action action = () => ;Task task = new Task(action);

async và await

Mã trên các bạn thấy, khi đối tượng người dùng Task khởi chạy bằng Start thì thread của Task chạy, và hầu như dòng codesau Start() được xử trí mà không xẩy ra khóa lại. Như đã nói trên, thread chạy - và khi delegate kết thúc kết trái trả vềlưu sinh hoạt task.Result

Vấn đề là khi truy vấn task.Result để đọc kết quả trả về, thì dòng code đó sẽ chờ mang lại Task trả thànhđể gọi dẫn đến chiếc code tiếp nối không được triển khai - bởi vì thread gọi lại bị block, ví dụ cập nhật hàm Async1để thấy rõ điều đó.

public static Task Async1 (string thamso1, string thamso2) { // tạo trở thành delegate trả về hình trạng string, có một tham số object Func myfunc = (object thamso) => // Đọc thông số (dùng kiểu rượu cồn - xem kiểu cồn để biết bỏ ra tiết) dynamic ts = thamso; for (int i = 1; i task = new Task (myfunc, new x = thamso1, y = thamso2 ); task.Start(); // chạy thread // Làm gì đó sau khi chạy Task tại đây Console.Write
Line("Async1: Làm nào đấy sau khi task chạy"); string ketqua= task.Result; // khóa (block) thread cha - đợi task ngừng Console.Write
Line("Làm gì đấy khi task đang kết thúc");
return task;

*
Khi Async1 được call 1 từ thread chính, nó khác trường hợptrước - thread chạy tuy nhiên hàm ko trả về ngay nhanh chóng - dẫn đếnthread bị khóa - Async2 ko được chạy cho tới khi thread vào Async1 kết thúc.

Bạn thấy thread trong Async1 kết thức 2, thì Async2 new được gọi 3, thời điểm đó task trong nó new chạy 4

Vậy 2 task trong ASync1 với Async2 không được chạy đồng thời, task này chấm dứt mới chạy được task tê => công dụng của đa luồng, bất đồng nhất mất đi.

Giờ bạn mong muốn khi hotline Async1(), nó trả về ngay chớp nhoáng (nghĩa là ko khóa thread hotline nó, mặc dù ban đầu chạy một task) - vào khi bên phía trong Async1() vẫn đảm bảo, bao gồm đoạn code chỉ được thihành khi task vào nó xong (đoạn code phía đằng sau string ketqua = task.Result;)

Lúc này bạn cần sử dụng mang lại cặp từ bỏ khóa async và await. Thực hiện làm như sau:

Bước 1) tiếp tế khai báo tên hàm từ bỏ khóa async, nó mang lại trình biên dịch biết đây làhàm bất nhất quán - khi hotline nó - nó trả về ngay lập tức lập tức

public static async Task Async1 (string thamso1, string thamso2)Bước 2) trong thân của Async1, phải bao gồm đoạn code đợi task trả thành

await task; // đó là điểm không khóa thread chính, thread bao gồm chạy tiếp, task chạy tiếp