2012-05-17 14 views
6

मेरे पास दो विधियों, लोड() और प्रक्रिया() के साथ एक कक्षा है। मैं इन्हें व्यक्तिगत रूप से पृष्ठभूमि कार्यों, या अनुक्रम में चलाने में सक्षम होना चाहता हूं। मुझे ContinueWith() वाक्यविन्यास पसंद है, लेकिन मैं इसे काम करने में सक्षम नहीं हूं। मुझे जिस विधि के साथ जारी है उस पर मुझे एक कार्य पैरामीटर लेना है और प्रारंभिक विधि पर कार्य पैरामीटर नहीं हो सकता है।कार्य। संपर्क विधि के साथ कार्य तर्क की आवश्यकता है?

मैं इसे लैम्ब्डा अभिव्यक्तियों के बिना करना चाहता हूं, लेकिन क्या मैं या तो उनका उपयोग कर रहा हूं, किसी एक विधि पर कार्य पैरामीटर को मजबूर कर रहा हूं, या तीसरी विधि LoadAndProcess() बना रहा हूं?

void Run() 
{ 
    // doesn't work, but I'd like to do it 
    //Task.Factory.StartNew(MethodNoArguments).ContinueWith(MethodNoArguments); 

    Console.WriteLine("ContinueWith"); 
    Task.Factory.StartNew(MethodNoArguments).ContinueWith(MethodWithTaskArgument).Wait(); 

    Console.WriteLine("Lambda"); 
    Task.Factory.StartNew(() => { MethodNoArguments(); MethodNoArguments(); }).Wait(); 

    Console.WriteLine("ContinueWith Lambda"); 
    Task.Factory.StartNew(MethodNoArguments).ContinueWith(x => { 
      MethodNoArguments(); 
     }).Wait(); 
} 

void MethodNoArguments() 
{ 
    Console.WriteLine("MethodNoArguments()"); 
} 

void MethodWithTaskArgument(Task t = null) 
{ 
    Console.WriteLine("MethodWithTaskArgument()"); 
} 
+1

क्या आप वर्णन कर सकते हैं कि आप लैम्ब्डा अभिव्यक्तियों का उपयोग क्यों नहीं करना चाहते हैं? –

+0

मेरे पास जारी रखने के सिंटैक्स को पसंद करने के अलावा कोई वास्तविक कारण नहीं है और मुझे लगता है कि लैम्ब्डा अभिव्यक्ति इसे कम दिखने वाली गंदगी और समझने में अधिक कठिन लगती है। –

+0

क्या 'लोड' और' प्रक्रिया 'अनुक्रमिक रूप से एक दूसरे पर निर्भर करता है? क्या डेटा उनके बीच साझा किया गया है जहां थ्रेड सिंक्रनाइज़ेशन परेशानी हो सकती है? –

उत्तर

12

ContinueWith() के सभी भार के अलावा, पहले पैरामीटर एक प्रतिनिधि है कि एक Task लेता है, तो आप इसे करने के लिए एक parameterless प्रतिनिधि पारित नहीं कर सकते हैं।

मुझे लगता है कि लैम्ब्डा का उपयोग पूरी तरह से ठीक है और यह पठनीयता को नुकसान नहीं पहुंचाता है। और अपने कोड में लैम्ब्डा अनावश्यक रूप से अत्यधिक शब्द है:

Task.Factory.StartNew(MethodNoArguments).ContinueWith(_ => MethodNoArguments()) 

या, जैसा कि कोरी कार्सन एक टिप्पणी में कहा, अगर आप एक्सटेंशन विधि लिख सकते हैं:

public static Task ContinueWith(this Task task, Action action) 
{ 
    return task.ContinueWith(_ => action()); 
} 
4

स्वच्छ कोड जब आप एकाधिक निरंतरता का उपयोग लेखन , कि आसान नहीं है, हालांकि आप कोड क्लीनर बनाने के लिए कुछ नियमों का पालन कर सकते हैं:

  1. svick के जवाब से कम फार्म का उपयोग करें
  2. निरंतरता को बरकरार रखने से बचें। प्रत्येक निरंतरता के परिणाम को एक अलग चर में रखें और फिर एक अलग पंक्ति
  3. में जारी रखें, यदि निरंतरता कोड लंबा है, तो उसे लैम्ब्डा चर में संग्रहीत करें और फिर लैम्ब्डा के साथ जारी रखें।
  4. अपने कोड को क्लीनर बनाने के लिए इस "Then" विधि जैसी एक एक्सटेंशन विधि का उपयोग करें।

आप कुछ इस तरह, जो थोड़ा क्लीनर है करने के लिए अपने कोड बदल सकते हैं:

 var call1=Task.Factory.StartNew(()=>MethodNoArguments()); 
     var call2 = call1.ContinueWith(_ => MethodNoArguments()); 
     call2.Wait(); 

या यहाँ तक कि

 var call1 = Task.Factory.StartNew<Task>(MethodNoArguments); 
     var call2 = call1.Then(MethodNoArguments); 
     call2.Wait(); 

स्टीफन Toub फिर विस्तार और अन्य तरीकों से आप साफ कर सकते हैं पर चर्चा Processing Sequences of Asynchronous Operations with Tasks

इस समस्या को सी # 4 में अच्छा के लिए हल किया गया है। सी # 5 में आप async/a का उपयोग कर सकते हैं साफ कोड है कि मूल तुल्यकालिक संस्करण की तरह लग रहा है, जैसे बनाने के लिए कीवर्ड इंतजार:

static async Task Run() 
    { 
     await MethodNoArguments(); 
     await MethodNoArguments(); 
    } 

    static async Task MethodNoArguments() 
    { 
     await Task.Run(()=>Console.WriteLine("MethodNoArguments()")); 
    } 

दृश्य स्टूडियो 11 और .NET 4.5 ए गो लाइव लाइसेंस है तो आप शायद उन्हें का उपयोग करना प्रारंभ कर सकते हैं।

आप एक ही परिणाम प्राप्त करने के लिए सी # 4 में Async CTP का उपयोग कर सकते हैं। आप उत्पादन में Async सीटीपी का उपयोग कर सकते हैं क्योंकि यह एक लाइव लाइसेंस है। नकारात्मकता यह है कि जब आप सीटीपी और .NET 4.5 के बीच मतभेदों के कारण .NET 4.5 पर जाते हैं तो आपको अपने कोड में कुछ छोटे बदलाव करना होगा (उदाहरण के लिए सीटीपी में टास्क.रुन के बजाय टास्कएक्स.रुन है)।

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