2012-03-14 15 views
7

मैं इस पद्धति है कि एक टास्क शुरू होती है और पिछले cahined टास्क रिटर्न परिणाम प्राप्त करने के:मैं निरंतर कार्य उदाहरण कैसे शुरू कर सकता हूं?

public Task<double> GetTask() 
{ 
    return Task.Factory.StartNew((() => 10)) 
     .ContinueWith(i => 
     { 
      return i.Result + 2; 
     }) 
     .ContinueWith(i => 
     { 
      return (double)i.Result; 
     }); 
} 

मैं एक ही काम के लिए लौट रहे एक ही विधि लेकिन Task.Factory साथ स्वचालित रूप से इसे शुरू करने के बिना करना चाहते हैं इस तरह .StartNew:

public Task<double> GetTask2() 
{ 
    return new Task<int>((() => 10)) 
     .ContinueWith(i => 
     { 
      return i.Result + 2; 
     }) 
     .ContinueWith(i => 
     { 
      return (double)i.Result; 
     }); 
} 

वैसे भी मैं एक तरह से GetTask2 द्वारा लौटाए गए कार्य शुरू करने और परिणाम प्राप्त करने को खोजने के लिए सक्षम नहीं था। मैं इसे कैसे शुरू कर सकता हूं और परिणाम प्राप्त कर सकता हूं?

उत्तर

1

आप निम्न की तरह कुछ कर सकते हैं। एक उदाहरण के रूप में मैंने चित्रण उद्देश्यों के लिए तीन TextBox एस बनाए हैं।

पहले की तरह

public Task<double> GetTask() 
{ 
    // Return choice of task. 
    return new Task<double>(() => 10.0); 
} 

एक विधि का उपयोग तब की तरह (त्रुटि हैंडलिंग ommitting)

public Task<double> DefineTaskContinuation(Task<double> _task) 
{ 
    _task.ContinueWith(i => 
     { 
      textBox2.Text = (i.Result + 2).ToString(); 
      return i.Result + 2; 
     }, TaskScheduler.FromCurrentSynchronizationContext()) 
    .ContinueWith(i => 
     { 
      textBox3.Text = (i.Result + 2).ToString(); 
     }, TaskScheduler.FromCurrentSynchronizationContext()); 
    return _task; 
} 

अगर आप ऐसे स्वरूप में एक विधि का उपयोग कर कि चयनित Task के लिए जारी रखने का निर्माण अपने आवश्यक कार्य का चयन textBox1, textBox2 और textBox3 के साथ, आप इन पाठ बॉक्स को गणना के अनुसार

के रूप में आउटपुट का उपयोग कर भर सकते हैं
private void button1_Click(object sender, EventArgs e) 
{ 
    Task<double> task = DefineTaskContinuation(GetTask()); 
    task.Start(); 
    textBox1.Text = task.Result.ToString(); 
} 

आउटपुट:

The Results

मुझे आशा है कि इस मदद करता है।

संपादित करें: @usr द्वारा बहुत ही सही टिप्पणियों के कारण, उत्तर बदल दिया गया है। ध्यान दें कि TaskScheduler.FromCurrentSynchronizationContext() एक आवश्यकता नहीं है, लेकिन इसका उपयोग यूआई थ्रेड में मेरे प्रिंटिंग आउटपुट को सुविधाजनक बनाने के लिए किया जाता है। शुभकामनाएं।

+1

यह काम नहीं करेगा। आपको मूल, पहला कार्य शुरू करने की आवश्यकता है। श्रृंखला का अंतिम नहीं है। – usr

+0

क्यों? यह सवाल नहीं है। बस विधि से कार्य को तुरंत चालू करें। फिर इसे शुरू करें। सरल। – MoonKnight

+1

आप निरंतर कार्य पर शुरुआत कर रहे हैं। आप निरंतर कार्य शुरू नहीं कर सकते हैं। जब उसका उत्तराधिकारी पूरा हो जाता है तो यह स्वतः शुरू हो जाएगा। आप इसे शुरू करने के लिए मजबूर नहीं कर सकते हैं। – usr

2

कुछ इस तरह:

public Task<double> GetTask() 
{ 
    var rootTask = new Task<int>((() => 10)); 
    var continuationTask = rootTask 
     .ContinueWith(i => 
     { 
      return i.Result + 2; 
     }) 
     .ContinueWith(i => 
     { 
      return (double)i.Result; 
     }); 
    rootTask.Start(), 
    return continuationTask; 
} 

आप केवल बाद में काम शुरू करना चाहते हैं, तो आप अपने कार्य से लौट सकते हैं दोनों।

+0

यह एक व्यवहार्य समाधान है लेकिन मेरे प्रश्न का उत्तर नहीं है।वैसे भी धन्यवाद। – gigi

+0

मुझे आपके प्रश्न के बारे में क्या याद आया? यह व्यवहार्य क्यों है, लेकिन जवाब नहीं है? – usr

+0

बिंदु यह है कि मुझे एक टुपल वापस करने की आवश्यकता नहीं है, लेकिन अंतिम परिणाम लौटने वाला कार्य और इसे खोजने में सक्षम होना चाहिए, उदाहरण के लिए: task.Root()। प्रारंभ()। यदि आप प्रश्न शीर्षक पढ़ते हैं, तो यह स्पष्ट है। – gigi

0
[TestFixture] 
public class TaskTester 
{ 
    [Test] 
    public void Test() 
    { 
     Tuple<Task<int>, Task<double>> result = GetResult(); 
     result.Item1.Start(); 
     Assert.That(result.Item2.Result, Is.EqualTo(12)); 
    } 

    private static Tuple<Task<int>, Task<double>> GetResult() 
    { 
     var task1 = new Task<int>(() => 10); 
     Task<int> task2 = task1.ContinueWith(i => i.Result + 2); 
     Task<double> task3 = task2.ContinueWith(i => (double)i.Result); 
     return new Tuple<Task<int>, Task<double>>(task1, task3); 
    } 
} 
2

आप किसी अन्य Task, कि माता-पिता Task शुरू होता है, तो निरंतरता सेट और निरंतरता के परिणाम देता है बना सकते हैं। यद्यपि इसका नुकसान यह है कि यह उस धागे को अवरुद्ध कर सकता है, जो वास्तव में उस निरंतरता को पूरा करने की गणना करता है।

public static Task<double> GetTask() 
{ 
    return new Task<double>(
     () => Task.Factory.StartNew(() => 10) 
        .ContinueWith(
         i => 
         { 
          return i.Result + 2; 
         }) 
        .ContinueWith(
         i => 
         { 
          return (double)i.Result; 
         }).Result); 
} 
संबंधित मुद्दे