2011-11-14 32 views
54

Tôi có đoạn mã sau:Đi qua một tham số phương pháp sử dụng Task.Factory.StartNew

var task = Task.Factory.StartNew(CheckFiles, cancelCheckFile.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); 

private void CheckFiles() 
{ 
    //Do stuff 
} 

bây giờ tôi muốn sửa đổi CheckFiles để chấp nhận và số nguyên và một tham chiếu BlockingCollection

private void CheckFiles(int InputID, BlockingCollection<string> BlockingDataCollection) 
{ 
    //Do stuff 
} 

Tôi có thể' t dường như tìm cách bắt đầu tác vụ này như tôi đã làm ở trên.

Bạn có thể trợ giúp không?

Cảm ơn

Trả lời

94

Tùy chọn tốt nhất có thể là sử dụng biểu thức lambda đóng trên các biến bạn muốn hiển thị.

Tuy nhiên, hãy cẩn thận trong trường hợp này, đặc biệt nếu bạn đang gọi điều này trong vòng lặp. (Tôi đề cập đến điều này kể từ khi biến của bạn là một "ID", và điều này là phổ biến trong tình huống này.) Nếu bạn đóng trên biến trong phạm vi sai, bạn có thể nhận được một lỗi. Để biết chi tiết, hãy xem Eric Lippert's post on the subject. Điều này thường đòi hỏi thực hiện một tạm thời:

foreach(int id in myIdsToCheck) 
{ 
    int tempId = id; // Make a temporary here! 
    Task.Factory.StartNew(() => CheckFiles(tempId, theBlockingCollection), 
     cancelCheckFile.Token, 
     TaskCreationOptions.LongRunning, 
     TaskScheduler.Default); 
} 

Ngoài ra, nếu mã của bạn cũng giống như ở trên, bạn nên cẩn thận với việc sử dụng LongRunning gợi ý - với lịch trình mặc định, điều này gây ra mỗi công việc để có được chủ đề riêng của nó thay vì sử dụng ThreadPool. Nếu bạn đang tạo nhiều tác vụ, điều này có thể có tác động tiêu cực vì bạn sẽ không nhận được những lợi thế của ThreadPool. Nó thường hướng cho một duy nhất, nhiệm vụ dài chạy (do đó tên của nó), không phải cái gì đó sẽ được thực hiện để làm việc trên một mục của một bộ sưu tập, vv

+0

Cảm ơn. Tôi sẽ bắt đầu chúng trong một vòng lặp. Tuy nhiên tôi cần nó như LongRunning. Chương trình ban đầu của tôi làm việc với một tập tin nhưng bây giờ nó cần phải làm một số mã trên nhiều tập tin. Vì vậy, tôi cần phải vượt qua ID, BlockingCollection, CancellationTokenSoure và StreamReader. Tôi đã không đề cập đến các tham số phương thức phụ trong câu hỏi tuy nhiên – Jon

+1

@Jon: Chỉ cần đảm bảo kiểm tra phạm vi của các đối tượng đó ... Tôi vừa đề cập đến gợi ý LongRunning như một cái gì đó để bạn xem xét - Tôi sẽ nói rằng nó hiếm khi là một ý tưởng hay để sử dụng LongRunning, đặc biệt là trong .NET 4, nếu bạn đang bắt đầu nhiều tác vụ (ví dụ: làm việc trong một vòng lặp), vì threadpool thường sẽ cung cấp hành vi tốt hơn. –

+0

Vòng lặp chỉ là để bắt đầu các nhiệm vụ. Tối đa là 4-6 – Jon

5

Xây dựng tham số đầu tiên là một thể hiện của Action, ví dụ

var inputID = 123; 
var col = new BlockingDataCollection(); 
var task = Task.Factory.StartNew(
    () => CheckFiles(inputID, col), 
    cancelCheckFile.Token, 
    TaskCreationOptions.LongRunning, 
    TaskScheduler.Default); 
17
class Program 
{ 
    static void Main(string[] args) 
    { 
     Task.Factory.StartNew(() => MyMethod("param value")); 
    } 

    private static void MyMethod(string p) 
    { 
     Console.WriteLine(p); 
    } 
} 
4

Đối với đi qua một số nguyên duy nhất Tôi đồng ý với Reed Copsey của câu trả lời. Nếu trong tương lai bạn sẽ vượt qua các cấu trúc phức tạp hơn, cá nhân tôi muốn chuyển tất cả các biến của tôi thành một Kiểu ẩn danh. Nó sẽ giống như thế này:

foreach(int id in myIdsToCheck) 
{ 
    Task.Factory.StartNew((Object obj) => 
     { 
      var data = (dynamic)obj; 
      CheckFiles(data.id, theBlockingCollection, 
       cancelCheckFile.Token, 
       TaskCreationOptions.LongRunning, 
       TaskScheduler.Default); 
     }, new { id = id }); // Parameter value 
} 

Bạn có thể tìm hiểu thêm về nó trong tôi blog

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