tôi tin rằng TPL (TaskFactory.Startnew) hoạt động tương tự như ThreadPool.QueueUserWorkItem trong tôi rằng t xếp hàng hoạt động trên một chuỗi trong nhóm luồng.
Pretty much.
Từ những gì tôi đã đọc, có vẻ như không đồng bộ/chờ đợi "đôi khi" tạo chuỗi mới.
Thực ra, nó không bao giờ thực hiện. Nếu bạn muốn đa luồng, bạn phải tự mình thực hiện nó. Có một phương thức Task.Run
mới chỉ là viết tắt của Task.Factory.StartNew
và đây có lẽ là cách phổ biến nhất để bắt đầu một tác vụ trên nhóm luồng.
Nếu bạn đang xử lý cổng hoàn thành IO, tôi có thể thấy nó không phải tạo chuỗi mới nhưng nếu không tôi sẽ nghĩ nó sẽ phải làm.
Bingo. Vì vậy, các phương pháp như Stream.ReadAsync
sẽ thực sự tạo một bao bọc Task
xung quanh IOCP (nếu Stream
có IOCP).
Bạn cũng có thể tạo một số tác vụ "không phải là I/O, không phải CPU". Một ví dụ đơn giản là Task.Delay
, trả về một tác vụ hoàn thành sau một khoảng thời gian.
Điều thú vị về async
/await
là bạn có thể xếp hàng một số công việc để các hồ bơi thread (ví dụ, Task.Run
), làm một số I/O-bound hoạt động (ví dụ: Stream.ReadAsync
), và thực hiện một số hoạt động khác (ví dụ, Task.Delay
) ... và tất cả đều là nhiệm vụ! Chúng có thể được chờ đợi hoặc sử dụng trong các kết hợp như Task.WhenAll
.
Bất kỳ phương thức nào trả về Task
đều có thể là await
- không phải là phương thức async
. Các thao tác Task.Delay
và I/O-bound chỉ sử dụng TaskCompletionSource
để tạo và hoàn thành tác vụ - điều duy nhất được thực hiện trên nhóm luồng là hoàn thành nhiệm vụ thực tế khi sự kiện xảy ra (hết giờ, hoàn thành I/O, v.v.).
Tôi đoán rằng sự hiểu biết của tôi về FromCurrentSynchronizationContext luôn có chút mờ. Tôi luôn luôn thông qua chủ đề giao diện người dùng.
Tôi đã viết an article trên SynchronizationContext
. Phần lớn thời gian, SynchronizationContext.Current
:
- là ngữ cảnh giao diện người dùng nếu chuỗi hiện tại là một chuỗi giao diện người dùng.
- là ngữ cảnh yêu cầu ASP.NET nếu chuỗi hiện tại đang phục vụ yêu cầu ASP.NET.
- là ngữ cảnh của nhóm chủ đề khác.
Bất kỳ chủ đề nào có thể đặt SynchronizationContext
riêng của mình, vì vậy có những ngoại lệ đối với các quy tắc trên.
Lưu ý rằng mặc định Task
awaiter sẽ sắp xếp thời gian còn lại của async
phương pháp trên hiện hành SynchronizationContext
nếu nó không phải là null; nếu không nó sẽ đi vào hiện tại TaskScheduler
. Hôm nay không quan trọng như vậy, nhưng trong tương lai gần nó sẽ là một sự phân biệt quan trọng.
Tôi đã tự viết async
/await
intro trên blog của mình và Stephen Toub gần đây đã đăng một số xuất sắc async
/await
FAQ.
Về "đồng thời" và "đa luồng", hãy xem this related SO question. Tôi có thể nói async
cho phép đồng thời, có thể hoặc không thể đa luồng. Thật dễ dàng để sử dụng await Task.WhenAll
hoặc await Task.WhenAny
để xử lý đồng thời và trừ khi bạn sử dụng hồ bơi chủ đề một cách rõ ràng (ví dụ: Task.Run
hoặc ConfigureAwait(false)
), thì bạn có thể thực hiện nhiều thao tác đồng thời cùng một lúc (ví dụ: nhiều I/O hoặc khác các loại như Delay
) - và không có chuỗi nào cần thiết cho chúng. Tôi sử dụng thuật ngữ "đồng thời một luồng" cho loại kịch bản này, mặc dù trong máy chủ ASP.NET, bạn thực sự có thể kết thúc với "zero đồng thời đã đọc". Đó là khá ngọt ngào.
Thực ra, TaskCreationOptions.LongRunning không đảm bảo "chuỗi mới". Theo MSDN, * tùy chọn "LongRunning" chỉ cung cấp gợi ý cho trình lên lịch; nó không đảm bảo một chủ đề chuyên dụng. * Tôi thấy rằng trên con đường khó khăn. – eduncan911
@ eduncan911 mặc dù những gì bạn nói về tài liệu là chính xác, tôi tra mã nguồn TPL trong khi trở lại và tôi khá chắc chắn rằng trên thực tế, một chuỗi chuyên dụng mới luôn được tạo khi 'TaskCreationOptions.LongRunning' được chỉ định. –
@ZaidMasud: Bạn có thể muốn xem xét lại.Tôi biết nó đã được tổng hợp các chủ đề bởi vì 'Thread.CurrentThread.IsThreadPoolThread' đã trở lại đúng cho các chuỗi ngắn chạy của vài trăm mili giây. chưa kể đến các biến ThreadStatic mà tôi đã sử dụng chảy máu thành nhiều luồng, gây ra tất cả các loại havok. Tôi đã phải ép buộc mã của tôi để tạo mới nhiều Thread() s, cách học cũ, để đảm bảo một chủ đề chuyên dụng. Nói cách khác, tôi không thể sử dụng TaskFactory cho các chủ đề chuyên dụng. Tùy chọn, bạn có thể thực hiện 'TaskScheduler' của riêng bạn luôn trả về một chuỗi chuyên dụng. – eduncan911