Friday, August 14, 2009

WCF - Event-based asynchronous pattern

WCF Guidance for WPF Developers

Asynchronous proxies generated with svcutil support two modes of asynchronous operations: delegate-based opertations and event-based operations. Delegate-based asynchronous operations follow the traditional asynchronous delegate pattern whereby each call is broken into two: a begin operation, and an end operation.

Eg:

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IProjectService/GetProjects", ReplyAction="http://tempuri.org/IProjectService/GetProjectsResponse")]

System.Collections.ObjectModel.ObservableCollectionProject> GetProjects();

[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IProjectService/GetProjects", ReplyAction="http://tempuri.org/IProjectService/GetProjectsResponse")]

System.IAsyncResult BeginGetProjects(System.AsyncCallback callback, object asyncState);

System.Collections.ObjectModel.ObservableCollectionProject> EndGetProjects(System.IAsyncResult result);

The drawback of the delegate-based asynchronous pattern is that every callback must synchronize access to UI components, and to other instance members belonging to the main Window. This requires developers to write synchronization logic which quickly adds to code clutter, and can become hard to follow. The event-based pattern solves this problem by exposing an event that is executed on the UI thread that can be used to notify the client about the completion of the operation. This logic is encapsulated in the proxy. You can use the svcutil tool with the /async /targetClientVersion:Version35 option to generate proxies with Async event support.

This option adds a EventArgs type that inherits from the AsyncCompletedEventArgs type for each asynchronous operations on the service. Later in the code you can use the event based asynchronous pattern to as given in the example below to query the service methods.

__AsyncProxy = new WCFSampleProjects.Proxies.Async.ProjectServiceClient("ProjectServiceAsync");

__AsyncProxy.InnerChannel.Faulted += new EventHandler(AsyncProxyFaulted);

__AsyncProxy.GetProjectsAsync();

__AsyncProxy.GetProjectsCompleted += new EventHandlerGetProjectsCompletedEventArgs>((y, z) =>

{

var __Projects = z.Result;

__Projects.ToList<Project>().ForEach(item => Console.WriteLine(item.Title));

});

Thursday, August 13, 2009

Two .bat files for generating WCF proxies using SVCUTIL

I have wrapped my svcutil commands to generate proxies for my services in two .bat files which help me to generate my proxies without entering the syntax for the command every time I want to generate my proxies.

A simple proxy generating command file looks like

@echo off

:: The batch file generates a WCF proxy file based on the parameters passed to it

:: The command generate C# code files be default

:: Usage

:: SvcHelper <> <> <>

:start

if "%1"=="" goto error

if "%2"=="" goto error

if "%3"=="" goto error

svcutil /l:cs /ct:System.Collections.Generic.List`1 /n:*,%3 %1 /out:%2

:error

echo usage "SvcHelper <> <> <>"

Copy the content into a .bat file and name if SvcHelper.bat and use that for proxy generation.

The one used to generate proxies for WPF client with async option turned on looks like.

I have wrapped my svcutil commands to generate proxies for my services in two .bat files which help me to generate my proxies without entering the syntax for the command every time I want to generate my proxies.

A simple proxy generating command file looks like

@echo off

:: The batch file generates a WCF proxy file based on the parameters passed to it

:: The command generate C# code files be default

:: Usage

:: SvcHelper <> <> <>

:start

if "%1"=="" goto error

if "%2"=="" goto error

if "%3"=="" goto error

svcutil /l:cs /ct:System.Collections.Generic.List`1 /n:*,%3 %1 /out:%2

:error

echo usage "SvcHelper <> <> <>"

Copy the content into a .bat file and name if SvcHelper.bat and use that for proxy generation.

The one used to generate proxies for WPF client with async option turned on looks like.

@echo off

:: The batch file generates a WCF proxy file based on the parameters passed to it

:: The command generate C# code files be default

:: Usage

:: SvcHelperWPFAsync <> <> <>

:start

if "%1"=="" goto error

if "%2"=="" goto error

if "%3"=="" goto error

svcutil /t:code %1 /out:%2 /n:*,%3 /async /ct:System.Collections.ObjectModel.ObservableCollection`1 /r:"C:\Progra~1\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll" /l:cs

:error

echo usage "SvcHelperWPFAsync <> <> <>"