Async / Await vs Threads


100

Trong .Net 4.5 Microsoft đã thêm Async/Awaittính năng mới để đơn giản hóa mã hóa không đồng bộ. Tuy nhiên, tôi tự hỏi

  1. Có thể Async/Awaitthay thế hoàn toàn cách sử dụng cũ Threads?
  2. Async/Awaitkhả năng làm bất cứ điều gì một Threadcó thể làm không đồng bộ?
  3. Có thể Async/Awaitchỉ được sử dụng với một số phương pháp như WebClient.DownloadStringAsynchoặc tôi có thể chuyển đổi bất kỳ phương pháp đồng bộ để làm cho nó sử dụng Async/Awaitvà không để chặn các chủ đề chính?

2
Threads và Async / Await là các tính năng không liên quan. Bạn có thể kết hợp chúng nhưng không nhất thiết phải như vậy.
dtb

2
Tôi nghĩ rằng Async / Await đang làm điều tương tự như new Thread(() => {Some Work}).Start();đang làm ?! phải không
Roman Ratskey

2
Không. Giả định của bạn là không đúng. Bạn có thể nghĩ đến Task.Run (TPL), thường được kết hợp với Async / Await, nhưng cũng không liên quan và không nhất thiết phải sử dụng nó.
dtb

4
@dtb: Vậy khi nào thì sử dụng Async / Await và khi nào thì sử dụng Threads ?. Tôi thực sự bối rối về sự khác biệt giữa Task.Run, Thread.Start, Async / Await. Nếu bạn có thể cung cấp cho tôi với một lời giải thích tốt mà làm cho tôi hiểu sự khác nhau giữa chúng tôi sẽ rất thankfull
La Mã Ratskey

2
Async / await không tạo hoặc theo bất kỳ cách nào khác sử dụng luồng.
wRAR

Câu trả lời:


78

nó có thể thay thế hoàn toàn cách sử dụng cũ của Threads không?

Không. Một chuỗi có thể làm được nhiều điều hữu ích hơn. Chờ đợi được thiết kế đặc biệt để đối phó với một cái gì đó dành thời gian, điển hình nhất một I / O yêu cầu. Theo truyền thống được thực hiện với một cuộc gọi lại khi yêu cầu I / O hoàn tất. Viết mã dựa trên các lệnh gọi lại này là khá khó khăn, hãy chờ đợi để đơn giản hóa nó.

có khả năng làm những gì mà một Thread có thể làm không đồng bộ?

Đại khái. Await chỉ lo xử lý sự chậm trễ, nó không làm bất cứ điều gì mà một luồng làm. Biểu thức await , ở bên phải của từ khóa await, là những gì hoàn thành công việc. Lý tưởng nhất là nó không sử dụng một luồng nào cả, nó đăng một yêu cầu trình điều khiển và khi trình điều khiển hoàn thành việc truyền dữ liệu, nó sẽ tạo ra một cuộc gọi lại thông báo hoàn thành. Cho đến nay, mạng là cách sử dụng phổ biến nhất, độ trễ hàng trăm mili giây là phổ biến và là tác dụng phụ không thể tránh khỏi của các dịch vụ di chuyển từ máy tính để bàn hoặc mạng LAN sang "đám mây". Việc sử dụng đồng bộ các dịch vụ như vậy sẽ làm cho giao diện người dùng không phản hồi.

chỉ có thể được sử dụng với một số phương pháp như WebClient.DownloadStringAsync

Không. Bạn có thể sử dụng nó với bất kỳ phương thức nào trả về một Tác vụ. Các phương thức XxxxAsync () chỉ là những phương thức được nấu sẵn trong .NET framework cho các hoạt động phổ biến cần thời gian. Giống như tải dữ liệu từ máy chủ web.


4
Trong khía cạnh C # hiện đại, cách tiếp cận tốt nhất để đạt được Async-Callbacks trên các API bên ngoài là gì?
bonCodigo

5
Được đề cập trong đoạn cuối cùng, hãy sử dụng một Nhiệm vụ.
Hans Passant

Tôi mong đợi điều gì đó mà một luồng có thể làm mà không thể thực hiện được thông qua lập trình không đồng bộ làm ví dụ.
Saeed Neamati

1
Bạn có thể mở rộng về "Một chuỗi có thể làm nhiều điều hữu ích hơn." Sẽ rất hữu ích nếu bạn hiểu các tính năng mà chuỗi cung cấp asynckhông phù hợp.
Benjohn

1
Đáng nói await Task.Runcho công việc ràng buộc cpu. Nếu tôi hiểu đúng, điều đó đôi khi hoàn thành những gì mà người ta sẽ tạo ra một luồng hoặc một nhân viên nền, phải làm.
ToolmakerSteve

15

Tuyên bố chính thức về điều này. Mặc dù bạn nên hiểu sự khác biệt giữa luồng và lập trình không đồng bộ trước khi thay thế một cách mù quáng một thứ bằng những thứ khác.


Đây giống như tài nguyên đầu tiên tôi đọc về Threads và Async / Await rõ ràng và ngắn gọn.
Arman Bimatov

2
Câu trả lời này chỉ chứa một liên kết đến tài liệu. Vì liên kết có thể lỗi thời, câu trả lời cũng có thể lỗi thời - hoặc thậm chí tệ hơn - hoàn toàn vô dụng. Thay vào đó, chúng tôi khuyến khích người dùng Stack đăng các phần có liên quan của liên kết vào câu hỏi của họ.
HimBromBeere 19/02/18

1
Đáng buồn thay, tuyên bố chính thức không giải thích khi nào thực hiện await Task.Run. Có một đề cập ngắn gọn về Task.Run, nhưng nó không rõ ràng. Điểm mấu chốt là awaitbản thân nó sẽ không làm cho một tác vụ ràng buộc cpu chạy song song, do đó công việc như vậy nên được thực hiện thông qua await Task.Run.
ToolmakerSteve

1

Tôi nghĩ về nó theo cách này (và tôi nghĩ Microsoft cũng vậy nếu bạn xem https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110 ) #threads )

Async / await là một cách nhanh chóng để chạy một số mã trên chuỗi ứng dụng chính với ưu điểm là mã có thể tự tạm ngưng khi nó không có việc gì để làm và trả lại tiêu điểm cho luồng chính, "đánh thức" trên luồng chính khi đó. là kết quả nhận được và sau đó chuyển quá trình xử lý trở lại - bạn đoán nó - luồng chính. Hãy nghĩ về nó giống như một câu lệnh GOTO dựa trên sự kiện trong Basic có thể chuyển quyền kiểm soát qua lại cho một dòng thực thi cụ thể.

Ngược lại, một luồng là một luồng thực thi riêng biệt có thể chạy với các biến riêng của nó, v.v. trong đó - được cung cấp đủ phần cứng - việc thực thi diễn ra song song với luồng chính.

Nếu bạn có một ứng dụng GUI sẽ tải xuống một tệp và sau đó thực hiện điều gì đó với tệp đó khi nó được tải xuống - tôi sẽ triển khai điều đó bằng cách sử dụng phương thức async / await.

Tuy nhiên, nếu GUI của bạn cần tải xuống 5000 tệp - tôi sẽ tạo một chuỗi tải tệp xuống để xử lý vì luồng GUI chính có thể bị đóng băng trong khi quá trình thực thi được chuyển để xử lý việc tải xuống tệp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.