Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Thanks Cory! Your suggestion to use TaskCompletionSource is just what I needed. I've combined the use of a TaskCompletionSource with the <a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=22388" rel="nofollow">Lucian Wischik's Async CTP specification</a> to develop a pair of generic Silverlight 5 classes that can be used to Await any CLR, or routed event. Only the Async CTP (AsyncCtpLibrary_Silverlight) is required (The formidable Rx library is not needed). Here are the two classes:</p> <pre><code>Public Class AwaitableEvent(Of TResult) Private eta As EventTaskAwaiter(Of TResult) = Nothing Sub New(ByVal Sender As Object, ByVal EventName As String) eta = New EventTaskAwaiter(Of TResult) Dim ei as EventInfo = Sender.GetType.GetEvent(EventName) Dim d = [Delegate].CreateDelegate(ei.EventHandlerType, Me, "EventCompletedHandler", True, True) ei.AddEventHandler(Sender, d) End Sub Public Function GetAwaiter() As EventTaskAwaiter(Of TResult) Return eta End Function Private Sub EventCompletedHandler(ByVal sender As Object, ByVal e As TResult) eta.tcs.TrySetResult(e) End Sub End Class Public Class EventTaskAwaiter(Of TResult) Friend tcs As New TaskCompletionSource(Of TResult) Public ReadOnly Property IsCompleted As Boolean Get Return tcs.Task.IsCompleted End Get End Property Sub OnCompleted(r As Action) Dim sc = SynchronizationContext.Current If sc Is Nothing Then tcs.Task.ContinueWith(Sub() r()) Else tcs.Task.ContinueWith(Sub() sc.Post(Sub() r(), Nothing)) End If End Sub Function GetResult() As TResult If tcs.Task.IsCanceled Then Throw New TaskCanceledException(tcs.Task) If tcs.Task.IsFaulted Then Throw tcs.Task.Exception.InnerException Return tcs.Task.Result End Function End Class </code></pre> <p>Here's an example of using the AwaitableEvent class to Await mouse, keyboard and timer events.</p> <pre><code>Private Sub AECaller() GetMouseButtonAsync() MessageBox.Show("After Await mouse button event") GetKeyAsync() MessageBox.Show("After Await key event") GetTimerAsync() MessageBox.Show("After Await timer") End Sub Private Async Sub GetMouseButtonAsync() Dim ae As New AwaitableEvent(Of MouseButtonEventArgs)(LayoutRoot, "MouseLeftButtonDown") Dim e = Await ae MessageBox.Show(String.Format("Clicked {0} at {1},{2}", e.OriginalSource.ToString, e.GetPosition(LayoutRoot).X, e.GetPosition(LayoutRoot).Y)) End Sub Private Async Sub GetKeyAsync() Dim ae As New AwaitableEvent(Of KeyEventArgs)(LayoutRoot, "KeyDown") Dim e = Await ae MessageBox.Show(String.Format("Key {0} was pressed", e.Key.ToString)) End Sub Private Async Sub GetTimerAsync() Dim StopWatch As New DispatcherTimer StopWatch.Interval = New TimeSpan(TimeSpan.TicksPerSecond * 6) Dim ae As New AwaitableEvent(Of EventArgs)(StopWatch, "Tick") StopWatch.Start() Await ae MessageBox.Show(String.Format("It's {0}seconds later!", StopWatch.Interval.TotalSeconds)) StopWatch.Stop() End Sub </code></pre> <p>As expected the Await statement returns control to the calling function immediately. When the events are subsequently completed, Await assigns the result (the event args appropriate for the event being monitored) and the remaining code in the asynchronous method is then run.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload