'da C# async temsilci işlevi için nasıl bekleriz? C++
(farklı platformların paylaşılan kodu) arasındaki iletişim C#
(Windows Evrensel Uygulaması) ile ilgilidir. Aşağıdakilerin C++
'dan C#
'a nasıl bir işlev çağrısı yaptığımız olduğunu biliyoruz. YukarıdaC++/CX
C#
class FooCS
{
FooCS()
{
FooC c = new ref FooC();
c.m_GetSomeValueEvent = GetSomeValueEvent;
// Some other stuff ...
}
string GetSomeValueEvent()
{
// Some other stuff ...
return "Hello World";
}
}
C++
public delegate Platform::String GetSomeValueEventHandler();
class FooC
{
public:
event GetSomeValueEventHandler^ m_GetSomeValueEvent;
void someFunction(){
Platform::String^ str = m_GetSomeValueEvent();
// Some other stuff ...
}
}
çok yalındır. Ama sorun şu ki GetSomeValueEvent()
dizgisi veritabanından veri okuma gibi ağır bir görev yapmak ve ben async
yapmak zorundayım.
async Task<string> GetSomeValueEvent() {
// Some other stuff ...
return "Hello World";
}
Şimdi burada soru geliyor: Nasıl bu temsilci işlevi iadesi için benim C++
kod beklemeye yapabilirim? Başka bir deyişle, aşağıdaki imza ne için değiştirilmelidir?
public delegate Platform::String GetSomeValueEventHandler();
Çevremdeyim ve bu sorun için doğru terminolojiyi bulamıyorum. Bunun imkansız olduğundan emin olduğunuzu biliyorsanız, en azından bilmek güzel olurdu.
string GetSomeValueEvent() {
// Convert a async method to non-async one
var val = someAsyncMethod().Result;
// Some other stuff ...
return "Hello World";
}
Sen GetSomeValueEvent
kilitlenme önlemek için ana iş parçacığı üzerinde çalışmadığından emin olmalıyız: Sonunda
, bu yaptığımız budur.
İki olay aboneniz olduğunda bu, geri dönüş değeri için yalnızca bir tanesi kullanıldıkları için bozulur. Sınıf sadece bir abone görevi tamamlamak için bekleyecektir. Erteleme modelini kullanmak daha iyidir. –
@RaymondChen Katılıyorum, bundan bahsetmeliydim. Ancak bir olay işleyicisinden bir değer döndürmek gerçekten kötü bir fikirdir ve dürüst bir şekilde, ertelemesiz patterin bunu nasıl çözeceğini bilmiyorum. –
Windows Çalışma Zamanı modeli, bir 'GetDeferral' yöntemine ve sonuçları raporlamak için bazı mekanizmalara sahip bir' EventArgs' parametresini iletmektir. Her delege bir ertelenir, async eserini yapar, sonucu rapor etme mekanizması (belki bir 'SetResult' yöntemi, ya da sonucu bir koleksiyona ekleyerek) rapor eder, sonra erteleme işlemini tamamlar. Son erteleme tamamlandığında, arayan bildirilen tüm sonuçları denetler. –