Dienstag, 18. März 2014

Implementierung eines asynchronen WcfProxy

Vor einiger Zeit zeigte mir ein Kollege eine interessante Implementierung für einen Wcf Client Proxy, die er im Buch Professionell entwickeln mit Visual C# 2012: Das Praxisbuch. von Matthias Geirhos gefunden hat. Ziel war es das Verbindungsmanagement und ExceptionHandling an einer zentralen Stelle (einer statischen Klasse) abzuwickeln.

Leider war die Implementierung speziell für die synchronen Methodenaufrufe über den WebService gedacht, aus diesem Grund habe ich eine TAP-variante implementiert, die  mit async und await arbeitet:
Bitte bedenkt, dass dieser Code nur als Ansatz zu verstehen ist, hier fehlt noch einiges (Exception Handling, Logging, Kann man wirklich con.Close() aufrufen (?), retry connect,...)

    public static class WcfProxy
    {
        public static async Task CallAsync<T>(Action<T> webServiceMethod) where T : ICommunicationObject, new()
        {
            T con = new T();
            try
            {
                // open the connection
                await Task.Factory.FromAsync(con.BeginOpen, con.EndOpen, null);

                // call the method
                await Task.Factory.FromAsync<T>(webServiceMethod.BeginInvoke, webServiceMethod.EndInvoke, con, null);
            }
            catch (CommunicationException comEx)
            {
                // .. do something .. //
                System.Diagnostics.Debug.WriteLine(comEx.ToString());
            }
            finally
            {
                con.Close();
            }
        }

        public static async Task<TResult> CallAsync<T, TResult>(Func<T, TResult> webServiceFunction) where T : ICommunicationObject, new() where TResult : class
        {
            T con = new T();
            TResult res = null;
            try
            {
                // open the connection
                await Task.Factory.FromAsync(con.BeginOpen, con.EndOpen, null);

                // call the method
                res = await Task.Factory.FromAsync<T, TResult>(webServiceFunction.BeginInvoke, webServiceFunction.EndInvoke, con, null);
            }
            catch (CommunicationException comEx)
            {
                // .. do something .. //
                System.Diagnostics.Debug.WriteLine(comEx.ToString());
            }
            finally
            {
                con.Close();
            }
            return res;
        }

    }

Keine Kommentare:

Kommentar veröffentlichen