2011-11-14 13 views
54

का उपयोग कर एक विधि पैरामीटर पासिंग मैं निम्नलिखित कोड है:Task.Factory.StartNew

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

private void CheckFiles() 
{ 
    //Do stuff 
} 

मैं अब स्वीकार करने के लिए CheckFiles में संशोधन करना चाहते हैं और पूर्णांक और एक BlockingCollection संदर्भ

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

मैं कर सकते हैं ' जैसा कि मैंने ऊपर किया था, इस कार्य को शुरू करने का कोई तरीका नहीं दिख रहा है।

क्या आप मदद कर सकते हैं?

धन्यवाद

उत्तर

94

सबसे अच्छा विकल्प शायद लैम्ब्डा अभिव्यक्ति का उपयोग करना है जो वे चरों को बंद कर देता है जिन्हें आप प्रदर्शित करना चाहते हैं।

हालांकि, इस मामले में सावधान रहें, खासकर अगर आप इसे लूप में बुला रहे हैं। (मैं इसका उल्लेख करता हूं क्योंकि आपका चर एक "आईडी" है, और यह इस स्थिति में आम है।) यदि आप गलत दायरे में चर को बंद करते हैं, तो आप एक बग प्राप्त कर सकते हैं। विवरण के लिए, Eric Lippert's post on the subject देखें। डिफ़ॉल्ट अनुसूचक के साथ, इस के बजाय अपने स्वयं के समर्पित धागा प्राप्त करने के लिए प्रत्येक कार्य का कारण बनता है -

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

इसके अलावा, अगर अपने कोड से ऊपर की तरह है, तो आप LongRunning संकेत का उपयोग कर के साथ सावधान रहना चाहिए: यह आमतौर पर एक अस्थायी बनाने की आवश्यकता है थ्रेडपूल का उपयोग करने के लिए। यदि आप कई कार्य बना रहे हैं, तो इसका नकारात्मक प्रभाव होने की संभावना है क्योंकि आपको थ्रेडपूल के फायदे नहीं मिलेंगे। यह आमतौर पर एक एकल, लंबी चलने वाली कार्य (इसलिए इसका नाम), कुछ नहीं है कि एक संग्रह के एक आइटम पर काम करने के लागू किया जाएगा, आदि

+0

धन्यवाद

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 } 

आप इसके बारे में अधिक सीख सकते हैं: यह कुछ इस तरह दिखेगा। मैं उन्हें एक लूप में शुरू कर दूंगा। हालांकि मुझे इसे LongRunning के रूप में करने की ज़रूरत है। मेरा मूल कार्यक्रम एक फाइल के साथ काम करता था लेकिन अब इसे कई फाइलों पर कुछ कोड करने की जरूरत है। इसलिए मुझे आईडी, ब्लॉकिंग कोलेक्शन, रद्दीकरण टोकनसोअर और स्ट्रीम रीडर में पास करने की आवश्यकता है। मैंने प्रश्न में उन अतिरिक्त विधि पैरामीटर को नहीं जोड़ा है, हालांकि – Jon

+1

@ जोन: बस उन वस्तुओं के दायरे की जांच करना सुनिश्चित करें ... मैंने अभी आपके लिए विचार करने के लिए कुछ के रूप में लंबे समय तक संकेत का उल्लेख किया है - मैं कहूंगा कि इसका शायद ही कभी एक अच्छा विचार है LongRunning का उपयोग करने के लिए, विशेष रूप से .NET 4 में, यदि आप कई कार्य शुरू कर रहे हैं (यानी: एक लूप में काम करना), क्योंकि थ्रेडपूल आम तौर पर बेहतर व्यवहार प्रदान करेगा। –

+0

लूप केवल कार्य शुरू करने के लिए है। LongRunning के बारे में 4-6 – Jon

5

Action का एक उदाहरण है, उदा पहले पैरामीटर का निर्माण

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

के लिए तैयार है एक भी पूर्णांक मैं रीड Copsey के साथ सहमत गुजर के लिए जवाब। यदि भविष्य में आप अधिक जटिल संरचनाएं पारित करने जा रहे हैं, तो मैं व्यक्तिगत रूप से बेनामी प्रकार के रूप में अपने सभी चर को पारित करना चाहता हूं। में मेरी blog

संबंधित मुद्दे