2015-01-13 17 views
7

olarak beni bir görevi geçme:, işte bu mümkün olup olmadığı emin değilim parametre

Ben

async Task MethodA(...) 
{ 
    // some code 
    // a call to specific Async IO bound method 
    // some code 
} 

vardır da MethodB(), MethodC() vb birden gerçekleştirmek için bir eylem dizisini var ve tüm spesifik olarak Async IO bağlı yöntemine yapılan çağrı haricinde tamamen aynı koda sahiptir. Bir yöntem işaretçisini bir yönteme iletmenin bir yolunu bulmaya çalışıyorum, böylece daha sonra bir Yöntem() içinde yürütebiliriz.

Ne ben şu anda yapıyorum şudur:

private async Task Method(Func<Task<Entity>> func) 
{ 
    // some code 
    var a = await task.Run(func); 
    // some code 
} 

var task = async() => await CallToIOBoundTask(params); 
Method(task); 

Bu kod, ancak, GÇ bağlı görev için gerekli değildir, yeni bir iş parçacığı her seferinde çeker ve kaçınılmalıdır.

Yani, ThreadPool iş parçacığı kullanılmaması için kodu yeniden kodlamanın bir yolu var mı? Farklı IO çağrıları farklı yöntem imzaları olduğunu belirtmeye gerek de önemlidir

private async Task Method(Task<Entity> task) 
{ 
    // some code 
    var a = await task; 
    // some code 
} 

: Hedef Böyle bir koda sahip olmaktır. Ayrıca, bir görev yalnızca Method() gövdesinde yürütülmeye başlayabilir ve daha önce değil. Tabii

+0

Başlamak için async görevi için Yöntem() yöntemindeki ifadeye kadar beklemek istiyor musunuz? Eğer öyleyse, o zaman sorudaki kod örneğiniz yanlış (bir tane oluşturmak yerine bir _existing_ görevini beklemek), ve daha önce sağladığınız cevap istediğiniz şeydir. Ancak, sadece "Yöntem()" yöntemi çağrılmadan önce başladığınız bir görevi beklemek istiyorsanız, bunu kolayca yapabilirsiniz: sadece e.g. Bir aramanın dönüş değerini, 'Yöntem()' yöntemine yapılan çağrınızın argümanı olarak 'CallToIOBoundTask()' olarak iletin. –

+0

@PeterDuniho Sorunuzun bir cevabı, sorunun son cümlesidir - Görev yürütme yöntemini() yönteminde başlatmalıdır. – Goran

cevap

16

, basitçe, func çağırmak bir görev geri almak ve await:

async Task Method(Func<Task<Entity>> func) 
{ 
    // some code 
    var a = await func(); 
    // some code 
} 

Ayrıca, bu lambda ifade gönderirken, bu yapıyor hepsi bir async yöntemini çağırarak olduğundan kendisi bir görev verir, bu kendi içinde async olması gerekmez: sürece tüm bu çağrılar Task<Entity> dönmek olarak gayet

Method(() => CallToIOBoundTask(params)); 

. Eğer değilse, sadece Task'u kullanabilirsiniz (bu, işlemi başlatmak ve tamamlanmasını beklemek demektir) ve sonucu kullanamazsınız.

+0

Heh, Parantez olmadan denedim ve işe yaramadı. :) 2. öneriniz için, bu bölüm için IL ne üretecek:() => CallToIOBoundTask (params)? Bu bir asenkron Görev Yöntemi mi olacak, değil mi? Bu kodun geçersiz olarak üretilememesi. – Goran

+0

@Goran Bir "async" yöntemi olmayacaktır. Ancak, CallToIOBoundTask işlevi bir görev döndürdüğü için bir görev döndürecektir. Ayrıca, parametre bir 'Eylem' değil, 'Func > 'olduğu için geçersiz olamaz. Bu lambda'yı '() => {CallToIOBoundTask (params) 'i döndürerek genişletebildiğinizden emin olmak istiyorsanız; } 'aynen aynısıdır. – i3arnon

İlgili konular