2011-08-04 19 views
5

tamamladıktan sonra bildirim almak için nasıl, ben paralel olarak 2 uzun süren görevleri arayüzünde gösterilen gereken veri döndürecek olan hem çalıştırmanız gerekir.C# .NET Görevler: birden fazla görevi benim WPF uygulamasında

Ben hem görevleri tamamlamadan gerçek olmalıdır IsBusy denilen benim bakış modelinde bir özellik var.

2 uzun süren görev tamamlandığında bir bildirim nasıl gönderilir?

Task.WaitAll kullanmak istemiyorum, çünkü UI iş parçacığı engeller. Bu uzun çalışma görevlerinin paralel olarak çalışmasını istiyorum çünkü ContinueWith kullanarak görevleri zincirlemek istemiyorum.

cevap

4

Kullanım TaskScheduler.FromCurrentSynchronizationContext() ve TaskFactory.ContinueWhenAll iletecek (...) UI güncellemesi yapmak.

+0

Bu tam olarak aradığım şey. Çerçevede böyle bir şey olduğundan şüphe ettim, bunu bulamadım. – Mas

0

Bence cevabınız bir geri çağırmadır.

Uzun süren iplerinizi hazırlarken, bir yönteme başvuruda bulunun. Geri arama yöntemini görev yöntemine iletebilir veya Delegelerin BeginInvoke() özelliğine yerleşik bir AsyncCallback delege örneği oluşturabilirsiniz. Geri arama yöntemi IAsyncResult kabul belirli bir temsilci tanımına uyması zorunludur,

public void StartMyTwoTasks() 
{ 
    //I'm passing the callback to the task method directly; you may prefer to pass it to BeginInvoke() 
    var task1Lambda =()=>Task1(TaskCompleted); 
    var task2Lambda =()=>Task2(TaskCompleted); 

    task1Lambda.BeginInvoke(null,null); 
    task2Lambda.BeginInvoke(null,null); 
} 

public void Task1(Action<int> task1Complete) 
{ 
    //perform your long-running calculation or data retrieval/transformation here 
    Thread.Sleep(10000); 
    //when finished, call the callback method. 
    //You may need to use Control.Invoke() to make sure the callback is executed on the UI thread 
    //If you use the AsyncCallback feature of BeginInvoke/EndInvoke, you don't have to make the call here. 
    taskComplete(1); 
} 

public void Task2(Action<int> taskComplete) 
{ 
    //Ditto 
    Thread.Sleep(8000); 

    taskComplete(2); 
} 

public void Task1Complete(int taskNumber) 
{ 
    TasksComplete[taskNumber-1] = true; 
    If(TasksComplete.All(x=>x==true)) 
     DoSomethingOnceAllTasksAreComplete(); 
} 

AsyncCallback özelliğini kullanarak, ancak içinde düzgün çağırma hakkında endişelenmenize gerek yok: İşte

temel örnek senin yöntemin; çerçeve sizin için geri bildirimi işler:

Her iki model de sizin için iyi çalışmalıdır. Diğer seçenekler, tamamlandığında her yöntem tarafından yükseltilen bir olayın ayarlanmasını içerir. Olaylar hemen hemen aynı şekilde çalışacaktır, çünkü olaylar sadece bazı sözdizimi şekilli "çok döküm" delegelerdir.

0

Ne bir boolean bayrak (ler) her göreve gelen ve şu bayrakları izler ayrı başka izleyici dişe sahip olacak? Her görev, işlemden döndüklerinde karşılık gelen bayraklarını ayarlamalıdır. Ardından, izleme iş parçacığı, bayrakların ayarlanıp ayarlanmadığını denetler (yani, her iki görev bitti). İşlemler bittiyse, bir olayı tetikler, IsBusy'yi false olarak ayarlayın.

4

Tek bir yöntem, Bu görevleri kullanan üçüncü iş parçacığıdır ve iki görev tamamlanana kadar iş parçacığı çıkmasını geciktirmek için Task.WaitAll kullanır. Bu iş parçacığının sonunda bir olayı tetikleyebilir veya geri arama işlevini yürütebilirsiniz.

RunWorkerCompleted adlı yerleşik bir olayı olan BackgroundWorker'u kullanarak daha da kolaylaştırabilirsiniz. Bu sizi iş parçacığı havuzuna koyar, böylece bu iş parçacığını yönetmekle ilgili olmanız gerekmez.

3

Task.Factory.ContinueWhenAll ürününü deneyin. Bir dizi Tasks alır ve hepsi tamamlandığında bir işlemi zaman uyumsuz olarak başlatır. Her iki görevler tamamlandı sonra

İlgili konular