2013-03-06 22 views
10

Bu sorunu C# yönteminde kullanıyorum. Ben bir dll bir işlevini çağıran bir yöntem yaptım Phone.GetLampMode(); Şimdi Phone.GetLampMode hiçbir şey iade etmiyor. Veri 'onGetLampModeResponse' etkinliğinde bir olayda geri döner. OnGetLampModeResponse olayından veriyi alana kadar yöntemimde bekleyebilmemin bir yolu var mı?Olay yakalanana kadar iç yöntemi bekleyin

public bool checkLamp(int iLamp) 
{ 
    Phone.ButtonIDConstants btn = new Phone.ButtonIDConstants(); 
    btn = Phone.ButtonIDConstants.BUTTON_1; 
    btn += iLamp; 
    Phone.GetLampMode(btn, null); 

    return true; 
} 

private void Phone_OnGetLampModeResponse(object sender, Phone.GetLampModeResponseArgs e) 
{ 
    var test = e.getLampModeList[0].getLampMode.ToString();  
} 
+1

GetLampMode ikinci parametre nedir ? Tahmin edeyim: Kendinizi tanımlayabileceğiniz bir nesne? Ve bu olay, olay göndericisinde veya "e" içindeki göndericidir? EDIT: Evet, buna userState denir. Bu userState'i geri arama işlevindeki 'e' değişkenine geri alabilirsiniz. – sinni800

+0

"OnGetLampModeResponse" ile "true" olarak ayarlanmış ve "checkLamp" ile bir döngüde kontrol edilen bir global 'bool' tanımlayarak çirkin bir çözüm düşünebilirim. –

+0

@JohnWillemse oldukça çirkin ve olaylar için durum değişkenleri teslim kavramından beri yapılmamalıdır. – sinni800

cevap

9

bir çözüm AutoResetEvent kullanmaktır:

public bool checkLamp(int iLamp) 
{ 
    Phone.ButtonIDConstants btn = new Phone.ButtonIDConstants(); 
    btn = Phone.ButtonIDConstants.BUTTON_1; 
    btn += iLamp; 

    AutoResetEvent waitHandle = new AutoResetEvent(false); 

    // Pass waitHandle as user state 
    Phone.GetLampMode(btn, waitHandle); 

    // Wait for event completion 
    waitHandle.WaitOne(); 

    return true; 
} 

private void Phone_OnGetLampModeResponse(object sender, Phone.GetLampModeResponseArgs e) 
{ 
    var test = e.getLampModeList[0].getLampMode.ToString(); 

    // Event handler completed 
    // I guess there is some UserState property in the GetLampModeResponseArgs class 
    ((AutoResetEvent)e.UserState).Set(); 
} 

NOT: Statik sınıf/değişken olarak Phone kullandığınız İlan, bir sen Windows Phone geliştirmekte olduğumuz düşünebiliriz ... Durum böyle ise, WP ve async programlama kavramının tümünün olması, UI iş parçacığının gibi bir şekilde kilitlenmediğini unutmayın.

+2

waitHandle'ı global bağlama mı yerleştirdiniz? Ya birden fazla kez çalıştırırsanız ve beklemeniz tamamen sıkışırsa ne olur? Bu cevap nasıl oy alabilir? – sinni800

+0

@ sinni800 İyi yorum, ancak OP çoklu iş parçacığı hakkında bir şey belirtmedi. Sanırım sadece uyumsuz bir şey yapmak istiyor. Gerçekten çok iş parçacıklıysa, bekleme tanıtıcısı, yöntemin bir parametresi olarak geçirilmelidir. – ken2k

+0

kesinlikle HERHANGİ bir durumda userState olarak geçirilmelidir. "Yarış koşulları" gibi ölçülü şeyler yüzünden sonsuza dek takılmış bir iplik almayı riske atıyorsunuz. – sinni800

0

Varolan model Olay tabanlı Asenkron Modele (EAP) yakın gibi görünüyor. Bu tür bir deseni yeni Görev-tabanlı Async Pattern'e (TAP) nasıl dönüştürüleceğini açıklayan Interop with Other Asynchronous Patterns and Types numaralı makaleye bakmak isteyebilirsiniz.

Bir Task (veya Task<T> sahip olduktan sonra, sadece Wait bunun için can

Sen denenmemiş böyle bir şey() görünmelidir hangi bir asenkron yöntemde işleyicisi sarabilirsiniz
+0

Evet, Async anahtar kelimeleri mükemmel olurdu. – sinni800

2

.

public async Task<bool> checkLamp(int iLamp) 
{ 
    Phone.ButtonIDConstants btn = new Phone.ButtonIDConstants(); 
    btn = Phone.ButtonIDConstants.BUTTON_1; 
    btn += iLamp; 

    var tcs = new TaskCompletionSource<bool>(); 
    var handler = (sender, e) => { 
     Phone.OnGetLampModeResponse -= handler; 
     var test = e.getLampModeList[0].getLampMode.ToString(); 
     tcs.SetResult(true); 
    }; 
    Phone.OnGetLampModeResponse += handler; 

    Phone.GetLampMode(btn, null); 

    return tcs.Task; 
} 
sizin arama yönteminde

şu yazılır: Bu avantaj, kullanıcı arayüzü doe sahiptir

Süreç yanıt beklenirken engellenmez.

İşte bu konu hakkında bir blog girişi var. Framework 4.5'in gerekli olduğunu unutmayın.