2012-03-14 42 views
7

Ben sonuç almak için son cahined Görevi Görev başlatır ve döndüren bu yöntem:Bir devam görev görev örneğini nasıl başlatırım?

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

Ben Task.Factory ile otomatik olarak başlatmadan aynı yöntem aynı görevi dönen ama istiyorum böyle .StartNew:

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

Neyse GetTask2 tarafından döndürülen görevi başlatma ve sonuç almak için bir yol bulmak mümkün değildi. Nasıl başlatıp sonucu nasıl alabilirim?

cevap

1

Aşağıdaki gibi bir şey yapabilirsiniz. Örnek olarak, gösterim amacıyla üç tane TextBox s oluşturduk.

İlk Sonra şekliniz varsa

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; 
} 

(hata işleme ommitting) gibi bir yöntemi kullanarak seçili Task için devam inşa

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

gibi bir yöntemi kullanarak gerekli görevi seçin

aşağıdaki gibi textBox1, textBox2 ve textBox3, sen countinuation çıktı kullanan bu metin kutularını doldurmak olabilir
private void button1_Click(object sender, EventArgs e) 
{ 
    Task<double> task = DefineTaskContinuation(GetTask()); 
    task.Start(); 
    textBox1.Text = task.Result.ToString(); 
} 

Çıktı:

The Results

umarım bu yardımcı olur.

Düzenleme: @usr çok doğru yorumlarla nedeniyle, cevap değişmiştir. TaskScheduler.FromCurrentSynchronizationContext()'un bir gereksinim olmadığını, ancak yazdırma çıktısını UI iş parçacığına kolaylaştırmak için kullanıldığını unutmayın. Herşey gönlünce olsun. Böyle

+1

Bu işe yaramaz. Orijinal, ilk görevi başlatmanız gerekiyor. Zincirin son değil. – usr

+0

Neden? Bu soru değil. Sadece görevi yöntemden başlat. O zaman başla. Basit. – MoonKnight

+1

Devam görevini başlatmak için çağrı yapıyorsunuz. Devam görevini başlatamazsın. Antecendent tamamlandığında otomatik olarak başlar. Başlamak için zorlayamazsın. – usr

2

şey: Yalnızca sonra görevi başlatmak istiyorsanız

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; 
} 

, kendi işlevinden hem dönebilir.

+0

Bu, uygulanabilir bir çözümdür ancak soruma cevap değildir.Yine de teşekkürler. – gigi

+0

Sorunuzla ilgili neyi özledim? Bu neden mümkün, fakat bir cevap değil? – usr

+0

Buradaki nokta, bir tuple döndürmek istemiyorum, ancak son sonucu döndüren ve örneğin, örneğin: task.Root(). Start(). Soru başlığını okursanız, açık. – 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

Daha sonra, ebeveyn Task başlar devamını kurar ve devamında sonucunu döndüren başka Task, oluşturabilir. Her ne kadar bu sürekliliğin tamamlanması için gerekli olanı beklerken bir iş parçacığını engelleyebileceği dezavantajına sahiptir.

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); 
} 
İlgili konular