Ask a questionAsk a question
 

AnswerWhen to call proxy's CloseAsync

  • Thursday, November 12, 2009 7:00 AMMichel Miranda Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    My Silverlight application uses a WCF proxy generated by adding a service reference. When do I have to close the proxy?
    Is it safe to close it right after calling the service, before the asynchronous reponse arrives?

    private void proxy_GetUserCompleted(object sender, GetUserCompletedEventArgs e)
    {
    }
    
    Proxy proxy = new Proxy();
    proxy.GetUserCompleted += new EventHandler<GetUserCompletedEventArgs>(proxy_GetUserCompleted);
    proxy.GetUserAsync();
    proxy.CloseAsync();
    
    

    I can't find useful documentation or samples on the internet.
    Thanks in advance!

Answers

  • Thursday, November 12, 2009 6:25 PMChristopher Scrosati - MSFTMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    You should close your proxy when you don't expect further communication with the service.
    This includes making sure you got all the response for the requests you made.
    Christopher Scrosati, Software Design Engineer, WCF Silverlight, Microsoft Corp.
  • Monday, November 16, 2009 9:56 AMMog_LiangModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi Michel,

    By disassembling the RequestChannel, I found that it has a state check on BeginRequest, but doesn't have in EndRequest method, which implys that regardless the async call complete time, just call close after all service call will be OK.

    With my little experiment, I found it work as we expected

    service
        [ServiceContract(Namespace = "")]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        public class Service1
        {
            [OperationContract]
            public int DoWork(int second)
            {
                Thread.Sleep(TimeSpan.FromSeconds(second));
                return second;
            }
        }
    
    client
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Service1Client sc1 = new Service1Client();
                sc1.DoWorkCompleted += new EventHandler<DoWorkCompletedEventArgs>(sc1_DoWorkCompleted);
                sc1.CloseCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(sc1_CloseCompleted);
                
                sc1.DoWorkAsync(10);
                sc1.DoWorkAsync(2);
                sc1.CloseAsync();
            }
    
            void sc1_CloseCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else
                    MessageBox.Show("Closed");
            }
    
            void sc1_DoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else
                    MessageBox.Show(e.Result.ToString());
            }
    
    So, I would say you can call CloseAsync just after all service call.

    Mog Liang

All Replies

  • Thursday, November 12, 2009 10:49 AMPROGRAMMERLIVE Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Greetings,

    Link is given below.

    Hook into WCF proxy's generic begin and end operationRSS
    • http://forums.silverlight.net/forums/p/141648/317738.aspx#317738
    Service-Driven Apps With Silverlight 2 And WCF - Kindly look into this article.
    • http://msdn.microsoft.com/en-us/magazine/cc794260.aspx

    Hope this helps.

    Take Care

    PL
    Helping People To Solve Technical Problems
  • Thursday, November 12, 2009 1:17 PMMichel Miranda Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thanks for your response. I appreciate it.
    However, the first link references a thread that was started by myself ;-)
    The second link doesn't mention the close in case of asynchronous communication.
  • Thursday, November 12, 2009 6:25 PMChristopher Scrosati - MSFTMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    You should close your proxy when you don't expect further communication with the service.
    This includes making sure you got all the response for the requests you made.
    Christopher Scrosati, Software Design Engineer, WCF Silverlight, Microsoft Corp.
  • Friday, November 13, 2009 5:57 AMMichel Miranda Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Thanks for your response.

    I don't expect further communication with the service.
    I prefer to call CloseAsync right after calling the service method instead of calling it when receiving the asynchronous response.
    Is it safe to call CloseAsync right after calling the service, before the asynchronous reponse arrives, like the following example?

    Proxy proxy = new Proxy();
    proxy.GetUserCompleted += new EventHandler<GetUserCompletedEventArgs>(proxy_GetUserCompleted);
    proxy.GetUserAsync();
    proxy.CloseAsync();
    
    Michel Miranda
  • Monday, November 16, 2009 9:56 AMMog_LiangModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi Michel,

    By disassembling the RequestChannel, I found that it has a state check on BeginRequest, but doesn't have in EndRequest method, which implys that regardless the async call complete time, just call close after all service call will be OK.

    With my little experiment, I found it work as we expected

    service
        [ServiceContract(Namespace = "")]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        public class Service1
        {
            [OperationContract]
            public int DoWork(int second)
            {
                Thread.Sleep(TimeSpan.FromSeconds(second));
                return second;
            }
        }
    
    client
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Service1Client sc1 = new Service1Client();
                sc1.DoWorkCompleted += new EventHandler<DoWorkCompletedEventArgs>(sc1_DoWorkCompleted);
                sc1.CloseCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(sc1_CloseCompleted);
                
                sc1.DoWorkAsync(10);
                sc1.DoWorkAsync(2);
                sc1.CloseAsync();
            }
    
            void sc1_CloseCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else
                    MessageBox.Show("Closed");
            }
    
            void sc1_DoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else
                    MessageBox.Show(e.Result.ToString());
            }
    
    So, I would say you can call CloseAsync just after all service call.

    Mog Liang
  • Monday, November 16, 2009 5:02 PMMichel Miranda Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Mog Liang,

    Thanks a lot! This is realy useful.

    I need to hook into the OpenCompleted and CloseCompleted events to show a progress bar when the application is waiting for a response from the service.
    My CloseCompleted event handler works fine, but my OpenCompleted event handler doesn't get called. Strange.

    As a workaround I hook into the Opened and Closed events of the ClientBase's InnerChannel property. Now both event handlers are being called.
    Maybe you know why the OpenCompleted event handler doesn't get called.

    Michel