none
WCF ria service and Service Broker - how to work together? RRS feed

  • Question

  • Dear Gurus! 
    Silverlight client uses a wcf service  to report about the changes in the mssql database.  If I understand correctly, there should be something like:

    [OperationContractAttribute(AsyncPattern = true)] public IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState) { return AddEventChanges(callback); } public emergEvent EndServiceAsyncMethod(IAsyncResult r) {

    // Response sent to the client CompletedAsyncResult<emergEvent> result = r as CompletedAsyncResult<emergEvent>; result.Data.TimeDetected = DateTime.Now; return result.Data; } publicIAsyncResult AddEventChanges() { using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand cmd = new SqlCommand("Select id_event,name,description from dbo.events", connection)) { cmd.Notification = null; SqlDependency dependency = new SqlDependency(cmd); dependency.OnChange += new OnChangeEventHandler(WaitChange); connection.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { }

    // return IAsyncResult after WaitChange executed

    } } } public void WaitChange(object sender, SqlNotificationEventArgs e) {

    // Forms answer with emergencyEvent type

    // and starts the next cycle of waiting for a response

    AddEventChanges();

    }

    I am interesting how execute AddEventChanges() With a delay before executing  WaitChange procedure?


    • Edited by ATerentjev Friday, April 4, 2014 6:26 AM
    Friday, April 4, 2014 6:24 AM

Answers

  • My working example. In silverlight application:

    #region using
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using TestAsyncWCF.ServiceReference1;
    #endregion
    
    namespace TestAsyncWCF
    {
        public partial class MainPage : UserControl
        {
    
            myAsyncServiceClient proxy;
    
            public MainPage()
            {
                InitializeComponent();
    
                proxy = new myAsyncServiceClient();
                proxy.ServiceAsyncMethodCompleted += new EventHandler<ServiceAsyncMethodCompletedEventArgs>(proxy_GetUserCompleted);
    
                proxy.StartTrackingChangesAsync();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
    
                proxy.ServiceAsyncMethodAsync("");         
            }
    
    
            void proxy_GetUserCompleted(object sender, ServiceAsyncMethodCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    textBox1.Text = "Error getting the user.";
                }
                else
                {
                    textBox1.Text = e.Result.TimeDetected.ToString();
                    proxy.ServiceAsyncMethodAsync(""); 
                }
            }
        }
    }

    And service :

    using System;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    
    using System.Windows.Forms;
    
    using System.Text;
    using System.Threading;
    using System.Data.SqlClient;
    
    namespace TestAsyncWCF.Web
    {
        [ServiceContract(Namespace = "")]
        [SilverlightFaultBehavior]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        public class myAsyncService
        {
            [OperationContract]
            public void StartTrackingChanges()
            {
             string connectionString = @"Server=serverName; Initial Catalog=road; 
                                                    User ID =dependency_client; Password =111111; 
                                                    Trusted_Connection =False; Integrated Security=True; ";
                SqlDependency.Stop(connectionString);
                SqlDependency.Start(connectionString);
            }
            [OperationContractAttribute(AsyncPattern = true)]
            public IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState)
            {
                return new CompletedAsyncResult<emergEvent>(callback,asyncState);
            }
    
    public emergEvent EndServiceAsyncMethod(IAsyncResult r)
    {
      CompletedAsyncResult<emergEvent> result = r as CompletedAsyncResult<emergEvent>;
     emergEvent ev = new emergEvent();
     ev.TimeDetected = DateTime.Now;
     return ev;
    }
    public class emergEvent
        {
    
            public bool IsMember { get; set; }
    
            public string Name { get; set; }
    
            public int Age { get; set; }
    
            public DateTime TimeDetected { get; set; }
        } 
    
        // Simple async result implementation.
        class CompletedAsyncResult<T> : AsyncResult
        {
            T data;
            private const string connectionString = @"Server=serverName; Initial Catalog=road; 
                                                    User ID =dependency_client; Password =111111; 
                                                    Trusted_Connection =False; Integrated Security=True; ";
    
            public CompletedAsyncResult(AsyncCallback callback, object state) : base(callback, state)
            { 
                AddEventChanges();
            }
    
    
            public void AddEventChanges()
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    using (SqlCommand cmd = new SqlCommand("Select id_event,name,description from dbo.events", connection))
      {
        cmd.Notification = null;
         SqlDependency dependency = new SqlDependency(cmd);
     dependency.OnChange += new OnChangeEventHandler(WaitChange);
                        connection.Open();
                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {                    }
                    }
                }
            }
    
            public void WaitChange(object sender, SqlNotificationEventArgs e)
            {
                base.Complete(false);
            }
        }
    }

    And class AsyncResult:

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    namespace TestAsyncWCF.Web
    {
        public abstract class AsyncResult : IAsyncResult
        {
            static AsyncCallback asyncCompletionWrapperCallback;
            AsyncCallback callback;
            bool completedSynchronously;
            bool endCalled;
            Exception exception;
            public bool isCompleted;
            AsyncCompletion nextAsyncCompletion;
            object state;
    
            ManualResetEvent manualResetEvent;
    
            object thisLock;
    
            protected AsyncResult(AsyncCallback callback, object state)
            {
                this.callback = callback;
                this.state = state;
                this.thisLock = new object();
            }
    
            public object AsyncState
            {
                get
                {
                    return state;
                }
            }
    
            public WaitHandle AsyncWaitHandle
            {
                get
                {
                    if (manualResetEvent != null)
                    {
                        return manualResetEvent;
                    }
    
                    lock (ThisLock)
                    {
                        if (manualResetEvent == null)
                        {
                            manualResetEvent = new ManualResetEvent(isCompleted);
                        }
                    }
    
                    return manualResetEvent;
                }
            }
    
            public bool CompletedSynchronously
            {
                get
                {
                    return completedSynchronously;
                }
            }
    
            public bool HasCallback
            {
                get
                {
                    return this.callback != null;
                }
            }
    
            public bool IsCompleted
            {
                get
                {
                    return isCompleted;
                }
            }
    
            protected Action<Exception> OnCompleting { get; set; }
    
            object ThisLock
            {
                get
                {
                    return this.thisLock;
                }
            }
    
            protected Action<AsyncCallback, IAsyncResult> VirtualCallback
            {
                get;
                set;
            }
    
            protected void Complete(bool completedSynchronously)
            {
                this.completedSynchronously = completedSynchronously;
                if (OnCompleting != null)
                {
                    try
                    {
                        OnCompleting(this.exception);
                    }
                    catch (Exception exception)
                    {
                        this.exception = exception;
                    }
                }
    
                if (completedSynchronously)
                {
                    this.isCompleted = true;
                }
                else
                {
                    lock (ThisLock)
                    {
                        this.isCompleted = true;
                        if (this.manualResetEvent != null)
                        {
                            this.manualResetEvent.Set();
                        }
                    }
                }
    
                if (this.callback != null)
                {
                    if (VirtualCallback != null)
                    {
                        VirtualCallback(this.callback, this);
                    }
                    else
                    {
                        this.callback(this);
                    }
                }
            }
    
            protected void Complete(bool completedSynchronously, Exception exception)
            {
                this.exception = exception;
                Complete(completedSynchronously);
            }
    
            static void AsyncCompletionWrapperCallback(IAsyncResult result)
            {
                if (result.CompletedSynchronously)
                {
                    return;
                }
    
                AsyncResult thisPtr = (AsyncResult)result.AsyncState;
                AsyncCompletion callback = thisPtr.GetNextCompletion();
    
                bool completeSelf = false;
                Exception completionException = null;
                try
                {
                    completeSelf = callback(result);
                }
                catch (Exception e)
                {
                    completeSelf = true;
                    completionException = e;
                }
    
                if (completeSelf)
                {
                    thisPtr.Complete(false, completionException);
                }
            }
    
            protected AsyncCallback PrepareAsyncCompletion(AsyncCompletion callback)
            {
                this.nextAsyncCompletion = callback;
                if (AsyncResult.asyncCompletionWrapperCallback == null)
                {
                    AsyncResult.asyncCompletionWrapperCallback = new AsyncCallback(AsyncCompletionWrapperCallback);
                }
    
                return AsyncResult.asyncCompletionWrapperCallback;
            }
    
            AsyncCompletion GetNextCompletion()
            {
                AsyncCompletion result = this.nextAsyncCompletion;
                this.nextAsyncCompletion = null;
                return result;
            }
    
            protected static TAsyncResult End<TAsyncResult>(IAsyncResult result)
                where TAsyncResult : AsyncResult
            {
                if (result == null)
                {
                    throw new ArgumentNullException("result");
                }
    
                TAsyncResult asyncResult = result as TAsyncResult;
    
                if (asyncResult == null)
                {
                    throw new ArgumentException("result", "Invalid asyncResult");
                }
    
                if (asyncResult.endCalled)
                {
                    throw new InvalidOperationException("AsyncResult has already ended");
                }
    
                asyncResult.endCalled = true;
    
                if (!asyncResult.isCompleted)
                {
                    asyncResult.AsyncWaitHandle.WaitOne();
                }
    
                if (asyncResult.manualResetEvent != null)
                {
                    asyncResult.manualResetEvent.Close();
                }
    
                if (asyncResult.exception != null)
                {
                    // Rethrow the exception
                    throw asyncResult.exception;
                }
    
                return asyncResult;
            }
    
            protected delegate bool AsyncCompletion(IAsyncResult result);
        }
    }

    Monday, April 7, 2014 1:35 PM

All replies

  • Dear Gurus! 
    Silverlight client uses a wcf service  to report about the changes in the mssql database.  If I understand correctly, there should be something like:

    [OperationContractAttribute(AsyncPattern = true)] public IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState) { return AddEventChanges(callback); } public emergEvent EndServiceAsyncMethod(IAsyncResult r) {

    // Response sent to the client CompletedAsyncResult<emergEvent> result = r as CompletedAsyncResult<emergEvent>; result.Data.TimeDetected = DateTime.Now; return result.Data; } publicIAsyncResult AddEventChanges() { using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand cmd = new SqlCommand("Select id_event,name,description from dbo.events", connection)) { cmd.Notification = null; SqlDependency dependency = new SqlDependency(cmd); dependency.OnChange += new OnChangeEventHandler(WaitChange); connection.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { }

    // return IAsyncResult after WaitChange executed

    } } } public void WaitChange(object sender, SqlNotificationEventArgs e) {

    // Forms answer with emergencyEvent type

    // and starts the next cycle of waiting for a response

    AddEventChanges();

    }

    I am interesting how execute AddEventChanges() With a delay before executing  WaitChange procedure? Or how to make correctly? 

    Friday, April 4, 2014 6:29 AM
  • We have not released any WCF transport channels for Service Broker yet. But we did prototype some request/reply channels for the demo at PDC last year. You can get the source code from CodeGallery on GotDotNet. Just follow the 'samples' link from our homepage http://www.sqlservicebroker.com/
    Monday, April 7, 2014 7:32 AM
  • Is there any way how to solve the problem with using IAsyncResult realization? May be some example? 
    Monday, April 7, 2014 7:52 AM
  • My working example. In silverlight application:

    #region using
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using TestAsyncWCF.ServiceReference1;
    #endregion
    
    namespace TestAsyncWCF
    {
        public partial class MainPage : UserControl
        {
    
            myAsyncServiceClient proxy;
    
            public MainPage()
            {
                InitializeComponent();
    
                proxy = new myAsyncServiceClient();
                proxy.ServiceAsyncMethodCompleted += new EventHandler<ServiceAsyncMethodCompletedEventArgs>(proxy_GetUserCompleted);
    
                proxy.StartTrackingChangesAsync();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
    
                proxy.ServiceAsyncMethodAsync("");         
            }
    
    
            void proxy_GetUserCompleted(object sender, ServiceAsyncMethodCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    textBox1.Text = "Error getting the user.";
                }
                else
                {
                    textBox1.Text = e.Result.TimeDetected.ToString();
                    proxy.ServiceAsyncMethodAsync(""); 
                }
            }
        }
    }

    And service :

    using System;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    
    using System.Windows.Forms;
    
    using System.Text;
    using System.Threading;
    using System.Data.SqlClient;
    
    namespace TestAsyncWCF.Web
    {
        [ServiceContract(Namespace = "")]
        [SilverlightFaultBehavior]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        public class myAsyncService
        {
            [OperationContract]
            public void StartTrackingChanges()
            {
             string connectionString = @"Server=serverName; Initial Catalog=road; 
                                                    User ID =dependency_client; Password =111111; 
                                                    Trusted_Connection =False; Integrated Security=True; ";
                SqlDependency.Stop(connectionString);
                SqlDependency.Start(connectionString);
            }
            [OperationContractAttribute(AsyncPattern = true)]
            public IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState)
            {
                return new CompletedAsyncResult<emergEvent>(callback,asyncState);
            }
    
    public emergEvent EndServiceAsyncMethod(IAsyncResult r)
    {
      CompletedAsyncResult<emergEvent> result = r as CompletedAsyncResult<emergEvent>;
     emergEvent ev = new emergEvent();
     ev.TimeDetected = DateTime.Now;
     return ev;
    }
    public class emergEvent
        {
    
            public bool IsMember { get; set; }
    
            public string Name { get; set; }
    
            public int Age { get; set; }
    
            public DateTime TimeDetected { get; set; }
        } 
    
        // Simple async result implementation.
        class CompletedAsyncResult<T> : AsyncResult
        {
            T data;
            private const string connectionString = @"Server=serverName; Initial Catalog=road; 
                                                    User ID =dependency_client; Password =111111; 
                                                    Trusted_Connection =False; Integrated Security=True; ";
    
            public CompletedAsyncResult(AsyncCallback callback, object state) : base(callback, state)
            { 
                AddEventChanges();
            }
    
    
            public void AddEventChanges()
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    using (SqlCommand cmd = new SqlCommand("Select id_event,name,description from dbo.events", connection))
      {
        cmd.Notification = null;
         SqlDependency dependency = new SqlDependency(cmd);
     dependency.OnChange += new OnChangeEventHandler(WaitChange);
                        connection.Open();
                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {                    }
                    }
                }
            }
    
            public void WaitChange(object sender, SqlNotificationEventArgs e)
            {
                base.Complete(false);
            }
        }
    }

    And class AsyncResult:

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    namespace TestAsyncWCF.Web
    {
        public abstract class AsyncResult : IAsyncResult
        {
            static AsyncCallback asyncCompletionWrapperCallback;
            AsyncCallback callback;
            bool completedSynchronously;
            bool endCalled;
            Exception exception;
            public bool isCompleted;
            AsyncCompletion nextAsyncCompletion;
            object state;
    
            ManualResetEvent manualResetEvent;
    
            object thisLock;
    
            protected AsyncResult(AsyncCallback callback, object state)
            {
                this.callback = callback;
                this.state = state;
                this.thisLock = new object();
            }
    
            public object AsyncState
            {
                get
                {
                    return state;
                }
            }
    
            public WaitHandle AsyncWaitHandle
            {
                get
                {
                    if (manualResetEvent != null)
                    {
                        return manualResetEvent;
                    }
    
                    lock (ThisLock)
                    {
                        if (manualResetEvent == null)
                        {
                            manualResetEvent = new ManualResetEvent(isCompleted);
                        }
                    }
    
                    return manualResetEvent;
                }
            }
    
            public bool CompletedSynchronously
            {
                get
                {
                    return completedSynchronously;
                }
            }
    
            public bool HasCallback
            {
                get
                {
                    return this.callback != null;
                }
            }
    
            public bool IsCompleted
            {
                get
                {
                    return isCompleted;
                }
            }
    
            protected Action<Exception> OnCompleting { get; set; }
    
            object ThisLock
            {
                get
                {
                    return this.thisLock;
                }
            }
    
            protected Action<AsyncCallback, IAsyncResult> VirtualCallback
            {
                get;
                set;
            }
    
            protected void Complete(bool completedSynchronously)
            {
                this.completedSynchronously = completedSynchronously;
                if (OnCompleting != null)
                {
                    try
                    {
                        OnCompleting(this.exception);
                    }
                    catch (Exception exception)
                    {
                        this.exception = exception;
                    }
                }
    
                if (completedSynchronously)
                {
                    this.isCompleted = true;
                }
                else
                {
                    lock (ThisLock)
                    {
                        this.isCompleted = true;
                        if (this.manualResetEvent != null)
                        {
                            this.manualResetEvent.Set();
                        }
                    }
                }
    
                if (this.callback != null)
                {
                    if (VirtualCallback != null)
                    {
                        VirtualCallback(this.callback, this);
                    }
                    else
                    {
                        this.callback(this);
                    }
                }
            }
    
            protected void Complete(bool completedSynchronously, Exception exception)
            {
                this.exception = exception;
                Complete(completedSynchronously);
            }
    
            static void AsyncCompletionWrapperCallback(IAsyncResult result)
            {
                if (result.CompletedSynchronously)
                {
                    return;
                }
    
                AsyncResult thisPtr = (AsyncResult)result.AsyncState;
                AsyncCompletion callback = thisPtr.GetNextCompletion();
    
                bool completeSelf = false;
                Exception completionException = null;
                try
                {
                    completeSelf = callback(result);
                }
                catch (Exception e)
                {
                    completeSelf = true;
                    completionException = e;
                }
    
                if (completeSelf)
                {
                    thisPtr.Complete(false, completionException);
                }
            }
    
            protected AsyncCallback PrepareAsyncCompletion(AsyncCompletion callback)
            {
                this.nextAsyncCompletion = callback;
                if (AsyncResult.asyncCompletionWrapperCallback == null)
                {
                    AsyncResult.asyncCompletionWrapperCallback = new AsyncCallback(AsyncCompletionWrapperCallback);
                }
    
                return AsyncResult.asyncCompletionWrapperCallback;
            }
    
            AsyncCompletion GetNextCompletion()
            {
                AsyncCompletion result = this.nextAsyncCompletion;
                this.nextAsyncCompletion = null;
                return result;
            }
    
            protected static TAsyncResult End<TAsyncResult>(IAsyncResult result)
                where TAsyncResult : AsyncResult
            {
                if (result == null)
                {
                    throw new ArgumentNullException("result");
                }
    
                TAsyncResult asyncResult = result as TAsyncResult;
    
                if (asyncResult == null)
                {
                    throw new ArgumentException("result", "Invalid asyncResult");
                }
    
                if (asyncResult.endCalled)
                {
                    throw new InvalidOperationException("AsyncResult has already ended");
                }
    
                asyncResult.endCalled = true;
    
                if (!asyncResult.isCompleted)
                {
                    asyncResult.AsyncWaitHandle.WaitOne();
                }
    
                if (asyncResult.manualResetEvent != null)
                {
                    asyncResult.manualResetEvent.Close();
                }
    
                if (asyncResult.exception != null)
                {
                    // Rethrow the exception
                    throw asyncResult.exception;
                }
    
                return asyncResult;
            }
    
            protected delegate bool AsyncCompletion(IAsyncResult result);
        }
    }

    Monday, April 7, 2014 1:35 PM