15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

event-Based asynchronous Pattern ❘ 541<br />

delegate are all input parameters from the caller plus the AsyncOperation parameter for getting the status<br />

<strong>and</strong> mapping the result of the operation.<br />

public void LongTaskAsync(string input, object taskId)<br />

{<br />

AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(taskId);<br />

lock (userStateDictionary)<br />

{<br />

if (userStateDictionary.ContainsKey(taskId))<br />

throw new ArgumentException("taskId must be unique", "taskId");<br />

}<br />

userStateDictionary[taskId] = asyncOp;<br />

}<br />

Action longTaskDelegate = DoLongTask;<br />

longTaskDelegate.BeginInvoke(input, asyncOp, null, null);<br />

The method DoLongTask() is now called asynchronously by using the delegate. The synchronous method<br />

LongTask() can now be invoked to get the output value.<br />

Because an exception that might happen inside the synchronous method should not just blow up the<br />

background thread, any exception is caught <strong>and</strong> remembered with the variable e of type Exception.<br />

Finally, the CompletionMethod() is invoked to inform the caller about the result.<br />

// running in a background thread<br />

private void DoLongTask(string input, AsyncOperation asyncOp)<br />

{<br />

Exception e = null;<br />

string output = null;<br />

try<br />

{<br />

output = LongTask(input);<br />

}<br />

catch (Exception ex)<br />

{<br />

e = ex;<br />

}<br />

}<br />

this.CompletionMethod(output, e, false, asyncOp);<br />

With the implementation of the CompletionMethod, the userStateDictionary is cleaned up as the<br />

operation is removed. The PostOperationCompleted() method of the AsyncOperation object ends<br />

the lifetime of the asynchronous operation <strong>and</strong> informs the caller, using the onCompletedDelegate<br />

method. This method ensures that the delegate is invoked on the thread as needed for the application type.<br />

To get information to the caller, an object of type LongTaskCompletedEventArgs is created <strong>and</strong> passed to<br />

the method PostOperationCompleted().<br />

private void CompletionMethod(string output, Exception ex,<br />

bool cancelled, AsyncOperation asyncOp)<br />

{<br />

lock (userStateDictionary)<br />

{<br />

userStateDictionary.Remove(asyncOp.UserSuppliedState);<br />

}<br />

}<br />

}<br />

// results of the operation<br />

asyncOp.PostOperationCompleted(onCompletedDelegate,<br />

new LongTaskCompletedEventArgs(output, ex, cancelled,<br />

asyncOp.UserSuppliedState));<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!