2016-07-17 14 views
53

là gì tôi có Phương pháp:sự khác biệt giữa Task.Run() và Task.Factory.StartNew()

private static void Method() 
{ 
    Console.WriteLine("Method() started"); 

    for (var i = 0; i < 20; i++) 
    { 
     Console.WriteLine("Method() Counter = " + i); 
     Thread.Sleep(500); 
    } 

    Console.WriteLine("Method() finished"); 
} 

Và tôi muốn bắt đầu phương pháp này trong một nhiệm vụ mới. tôi có thể bắt đầu nhiệm vụ mới như thế này

var task = Task.Factory.StartNew(new Action(Method)); 

hay này

var task = Task.Run(new Action(Method)); 

Nhưng có bất kỳ sự khác biệt giữa Task.Run()Task.Factory.StartNew(). Cả hai người trong số họ đang sử dụng ThreadPool và bắt đầu Method() ngay lập tức sau khi tạo cá thể của Task. Khi chúng ta nên sử dụng biến thể đầu tiên và khi thứ hai?

+1

Thực ra, StartNew không phải sử dụng ThreadPool, xem blog tôi đã liên kết đến trong câu trả lời của tôi. Vấn đề là 'StartNew' theo mặc định sử dụng' TaskScheduler.Current' có thể là nhóm luồng nhưng cũng có thể là chuỗi giao diện người dùng. –

+0

Có thể trùng lặp của [Về việc sử dụng Task.Start(), Task.Run() và Task.Factory.StartNew()] (https://stackoverflow.com/questions/29693362/regarding-usage-of-task-start -task-run-and-task-factory-startnew) –

Trả lời

6

Tài liệu thứ hai được giới thiệu trong phiên bản .NET framework mới hơn và là recommended. Tùy chọn đầu tiên có nhiều tùy chọn hơn, tùy chọn thứ hai là viết tắt:

Phương pháp chạy giúp dễ dàng bắt đầu một tác vụ bằng cách sử dụng giá trị mặc định. Đó là một thay thế nhẹ cho Bắt đầu quá tải mới.

Và bằng cách viết tắt Ý tôi là một kỹ thuật shortcut:

public static Task Run(Action action) 
{ 
    return Task.InternalStartNew(null, action, null, default(CancellationToken), TaskScheduler.Default, 
     TaskCreationOptions.DenyChildAttach, InternalTaskOptions.None, ref stackMark); 
} 
62

Phương pháp thứ hai, Task.Run, đã được giới thiệu trong một phiên bản sau này của .NET framework (trong .NET 4.5).

Tuy nhiên, phương pháp đầu tiên, Task.Factory.StartNew, cung cấp cho bạn cơ hội để xác định nhiều điều hữu ích về chuỗi bạn muốn tạo, trong khi Task.Run không cung cấp điều này. Ví dụ:

Ví dụ: giả sử bạn muốn tạo chuỗi nhiệm vụ đang chạy dài. Nếu một thread của thread thread sẽ được sử dụng cho tác vụ này, thì điều này có thể được coi là một sự lạm dụng của pool thread.

Một điều bạn có thể làm để tránh điều này là chạy tác vụ trong một chuỗi riêng biệt. Một chủ đề mới được tạo ra sẽ được dành riêng cho tác vụ này và sẽ bị hủy khi công việc của bạn đã được hoàn thành. Bạn không có thể đạt được điều này với Task.Run, trong khi bạn có thể làm như vậy với Task.Factory.StartNew, như dưới đây:

Task.Factory.StartNew(..., TaskCreationOptions.LongRunning); 

Vì nó được nêu here:

Vì vậy, trong .NET Framework 4.5 Xem trước nhà phát triển, chúng tôi đã giới thiệu phương thức Task.Run mới . này không có cách nào obsoletes Task.Factory.StartNew, nhưng thay vì chỉ đơn giản nên được coi như là một cách nhanh chóng để sử dụng Task.Factory.StartNew mà không cần phải xác định một loạt các thông số . Đó là một lối tắt. Trên thực tế, Task.Run thực ra là được triển khai theo cùng một logic được sử dụng cho Task.Factory.StartNew, chỉ truyền trong một số tham số mặc định. Khi bạn chuyển một Hành động tới Tác vụ.Chạy:

Task.Run(someAction); 

đó là chính xác tương đương với:

Task.Factory.StartNew(someAction, 
    CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); 
+3

Tôi có một đoạn mã mà bảng sao kê 'đó là chính xác tương đương với' không giữ. – Emaborsa

+1

@Emaborsa Tôi sẽ đánh giá cao Nếu bạn có thể đăng đoạn mã này và xây dựng lập luận của bạn. Cảm ơn trước ! – Christos

+0

Họ là 40 loc với một số phụ thuộc ... làm thế nào để tôi làm gì? – Emaborsa

14

Xem this blog article mô tả sự khác biệt. Về cơ bản thực hiện:

Task.Run(A) 

là giống như thực hiện:

Task.Factory.StartNew(A, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); 
-3

Trong ứng dụng của tôi trong đó kêu gọi hai dịch vụ, tôi so với cả Task.Run và Task.Factory.StartNew. Tôi thấy rằng trong trường hợp của tôi cả hai đều làm việc tốt. Tuy nhiên, thứ hai là nhanh hơn.

Các vấn đề liên quan