How to animate GIF while waiting for a WCF response?

LarsNess
LarsNess used Ask the Experts™
on
I have a GIF animation on a separate windows form that i show before making a WCF call. The call takes a few minutes to complete. My idea was to have the GIF anim running while waiting and then close it after the WCF response. This works, but the GIF animation is not running. Can anyone help me with this? I am using C# and VS2008.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Miguel OzSenior Software Engineer
Top Expert 2009

Commented:
Make the WCF call asynchronously, then your program can display a winform with the gif picture or progress bar; whenl you call is completed/finished then the winform dissapears.
Miguel OzSenior Software Engineer
Top Expert 2009

Commented:
How to: Call WCF Service Operations Asynchronously:
http://msdn.microsoft.com/en-us/library/ms730059.aspx

Author

Commented:
Thanks. I am afraid the article was a bit too complicated for me to get into within the time I have. I use the Service References functionality in VS2008 to be updated between the client and the service. I have attached the code I use for the call. Is there an easy way to adjust it to be async?
List<KLEXServiceReference.ForfatterAntallTegn> fList;
            try {
                using (KLEXServiceReference.KLEXWCFServiceClient sc = new KLEXNavigator.KLEXServiceReference.KLEXWCFServiceClient()) {
                    KLEXServiceReference.CountCharactersPrForfatterRequest r = new KLEXNavigator.KLEXServiceReference.CountCharactersPrForfatterRequest();
                    KLEXServiceReference.CountCharactersPrForfatterResponse pr = sc.CountCharactersPrForfatter(r);
                    fList = pr.CountCharactersPrForfatterResult;
                }

Open in new window

Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

Miguel OzSenior Software Engineer
Top Expert 2009

Commented:
OK, another way to do it is using BackgroundWorker if you are using winforms or silverlight.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Use DoWork event to put your web call.
For example:
use this code to replace your long call:
KLEXServiceReference.KLEXWCFServiceClient sc = new KLEXNavigator.KLEXServiceReference.KLEXWCFServiceClient();
BackgroundWorker bgWorker;
bgWorker = new BackgroundWorker();
bgWorker.RunWorkerAsync(sc);
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
            bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
//Show splash screen
 
=====then handle the events are=====


        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            KLEXServiceReference.KLEXWCFServiceClient service = (KLEXServiceReference.KLEXWCFServiceClient)e.Argument;
KLEXServiceReference.CountCharactersPrForfatterRequest r = new KLEXNavigator.KLEXServiceReference.CountCharactersPrForfatterRequest();
                    KLEXServiceReference.CountCharactersPrForfatterResponse pr = sc.CountCharactersPrForfatter(r);
                    e.Result = pr.CountCharactersPrForfatterResult;  
        }
 
       private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
           if (e.Error != null)
          {
             MessageBox.Show(e.Error.ToString());
             return;
          }
          //Hide your splash form
          fList =   e.Result as List<KLEXServiceReference.ForfatterAntallTegn>;
        }  

Author

Commented:
Thanks a LOT :-)

Author

Commented:
I have tried the solution and I thought I got it to work (hence the closed status). But I keep getting an exception (see image as well):

The communication object, System.ServiceModel.Channels.HttpChannelFactory+HttpRequestChannel, cannot be used for communication because it has been Aborted.

The exception occurs in this line:
KLEXServiceReference.CountCharactersPrForfatterResponse pr = service.CountCharactersPrForfatter(r);  (in bgWorker_DoWork method)

Please note that I had to change the call from sc.CountCharactersPrForfatter(r) (your example) to service.CountCharactersPrForfatter(r) - as sc is out of scope in the event handler.

Did I do something wrong? I also trid to declare sc globally and use that in the event handler, but that didn't work either.


 
private void mnuAdministrasjonPublikasjonsoversikt_Click(object sender, EventArgs e) {
            this.Cursor = Cursors.WaitCursor;
//            frmWait FormWait = new frmWait();
//            FormWait.Location = new Point(this.Left + 366, this.Height / 2 + this.Top - 133);
//            FormWait.Show(this);
            splitContainerSearch.Enabled = false;
            dgvResult.Enabled = false;
            rtxtSummary.Enabled = false;

            try {
                using (KLEXServiceReference.KLEXWCFServiceClient sc = new KLEXNavigator.KLEXServiceReference.KLEXWCFServiceClient()) {
                    BackgroundWorker bgWorker = new BackgroundWorker();
                    bgWorker.RunWorkerAsync(sc);
                    bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
                    FormWait = new frmWait();
                    FormWait.Location = new Point(this.Left + 366, this.Height / 2 + this.Top - 133);
                    FormWait.Show(this);
//                    KLEXServiceReference.CountCharactersPrForfatterRequest r = new KLEXNavigator.KLEXServiceReference.CountCharactersPrForfatterRequest();
//                    KLEXServiceReference.CountCharactersPrForfatterResponse pr = sc.CountCharactersPrForfatter(r);
//                    fList = pr.CountCharactersPrForfatterResult;
                }
                rtxtSummary.Clear();
                string list = "";
                foreach (KLEXServiceReference.ForfatterAntallTegn f in fList) {
                    list += f.Initialer.Trim() + "\t  --  " + f.AntallTegn.ToString() + " tegn" + "\t  --  " + f.Navn.Trim();
                    list += Environment.NewLine;
                }
                rtxtSummary.SelectedText = list;
//                FormWait.Close();
                if (MessageBox.Show("Vil du lagre resultatet som CSV fil?", "Lagre resultat?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes) {
                    SaveFileDialog saveDialog = new SaveFileDialog();
                    saveDialog.Filter = "CSV file|*.csv";
                    saveDialog.Title = "Lagre CSV fil";
                    saveDialog.ShowDialog();
                    if (saveDialog.FileName != "") {
                        StreamWriter sw = new StreamWriter(saveDialog.FileName, false);
                        foreach (KLEXServiceReference.ForfatterAntallTegn f in fList) {
                            sw.WriteLine(f.Initialer + ";" + f.Navn + ";" + f.AntallTegn);
                        }
                    }
                }
            } catch (Exception ex) {
                common.Log(" (mnuAdministrasjonPublikasjonsoversikt_Click) " + ex.Message.ToString());
                if (FormWait.Visible) FormWait.Close();
            }

            splitContainerSearch.Enabled = true;
            dgvResult.Enabled = true;
            rtxtSummary.Enabled = true;
            this.Cursor = Cursors.Default;
        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e) {
//            try {
                KLEXServiceReference.KLEXWCFServiceClient service = (KLEXServiceReference.KLEXWCFServiceClient)e.Argument;
                KLEXServiceReference.CountCharactersPrForfatterRequest r = new KLEXNavigator.KLEXServiceReference.CountCharactersPrForfatterRequest();
                KLEXServiceReference.CountCharactersPrForfatterResponse pr = service.CountCharactersPrForfatter(r);
                e.Result = pr.CountCharactersPrForfatterResult;
//            } catch (Exception ex) {
//                common.Log(" (bgWorker_DoWork) " + ex.Message.ToString());
//            }
        }

        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
            if (e.Error != null) {
                MessageBox.Show(e.Error.ToString());
                return;
            }
            if (FormWait.Visible) FormWait.Close();
            fList = e.Result as List<KLEXServiceReference.ForfatterAntallTegn>;
        }

Open in new window

exc.jpg
Senior Software Engineer
Top Expert 2009
Commented:
Your problem is line 11
using (KLEXServiceReference.KLEXWCFServiceClient sc = new KLEXNavigator.KLEXServiceReference.KLEXWCFServiceClient())

Make sc a field object and keep it alive for the lifetime of your form or make it null after  bgWorker_RunWorkerCompleted.

Also replace lines 12 ot 15 with:
BackgroundWorker bgWorker = new BackgroundWorker();
                    bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
                    bgWorker.RunWorkerAsync(sc);  //This will start the thread, but events must be set before this call.

Author

Commented:
Brilliant! :-)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial