5

In my project, whenever a long process in being executed, a small form is displayed with a small animated gif file. I used this.Show() to open the form and this.Close() to close the form. Following is the code that I use.

public partial class PlzWaitMessage : Form
{
   public PlzWaitMessage()
   {
      InitializeComponent();
   }

   public void ShowSpalshSceen()
   {
      this.Show();
      Application.DoEvents();
   }

   public void CloseSpalshScreen()
   {
      this.Close();
   }
}

When the form opens, the image file do not immediately start animating. And when it does animate, the process is usually complete or very near completion which renders the animation useless. Is there a way I can have the gif animate as soon as I load the form?

ChrisF
  • 134,786
  • 31
  • 255
  • 325
Rabin
  • 1,563
  • 4
  • 20
  • 44

3 Answers3

4

Why not using threads? It's always good idea to learn something new.

You could simply put your "long process" in background thread, and use events to report to presentation layer, for example:

// in your "long process" class
public event Action<double> ReportCompletition;

// this method will start long process in separate background thread
public void Start()
{ 
    Thread thread = new Thread(this.LongProcess);
    thread.IsBackground = true;
    thread.Start();
}

private void LongProcess()
{
    // do something
    // report 10% completition by raising event
    this.ReportCompletition(0.1);
    // do something more
    this.ReportCompletition(0.5);
    // ... and so on
}

This way, all you have to do is implement simple method in your Form/UI, which will consume this information.

public partial class MainApplicationWindow : Form
{
    private LongProcessClass _longProcess;

    public MainApplicationWindow
    {
        this.InitializeComponent();
        this._longProcess = new LongProcessClass();
        // bind UI updating method to long process class event
        this._longProcess.ReportCompletition += this.DisplayCompletitionInfo;
    }

    private void DisplayCompletitionInfo(double completition)
    {  
        // check if control you want to display info in needs to be invoked
        // - request is coming from different thread
        if (control.InvokeRequired)
        {
            Action<double> updateMethod = this.DisplayCompletitionInfo;
            control.Invoke(updateMethod, new object[] { completition });
        }
        // here you put code to do actual UI updating, 
        // eg. displaying status message
        else
        {
            int progress = (int) completition * 10;
            control.Text = "Please wait. Long process progress: " 
                + progress.ToString() + "%";
        }
    }

Of course, you can report anything you like from within long process. Be it completition rate, ready to display string messages, anything. You can also use events to report that long process has finished, broke, or any long process data you wish.

For more detailed information on this topic you might want to check MSDN tutorials on Threading and Events.

k.m
  • 30,794
  • 10
  • 62
  • 86
3

You should do the "long process" in a separate thread. I advice using the BackgroundWorker.

This will make your code more difficult though. One of the main reasons is, that you cannot communicate with the UI from the background thread.

Also note the warning from the linked page:

Caution

When using multithreading of any sort, you potentially expose yourself to very serious and complex bugs. Consult the Managed Threading Best Practices before implementing any solution that uses multithreading.

If this is too difficult, you could call Application.DoEvents very frequent from your "long process" code.

Whatever you choose, this will make it possible for the user to interact with your form. For instance closing it. You should be aware of this.

Community
  • 1
  • 1
GvS
  • 52,015
  • 16
  • 101
  • 139
  • The application process, not the GIF shown process, of course. – Ignacio Soler Garcia Jun 18 '10 at 10:13
  • Due to my inexperience, I do not want to use threads. I am using the Application.DoEvents() function. In my code, I've called the ShowSpalshSceen() using the following code. PlzWaitMessage pMess = new PlzWaitMessage(); pMess.ShowSpalshSceen(); LoadReport(); pMess.CloseSpalshScreen(); Am I not doing it right here? – Rabin Jun 18 '10 at 10:31
  • By the way the picture box on my form sits on top of a panel that fills the entire of the small message form. – Rabin Jun 18 '10 at 10:32
  • @Rabin, if you want the UI to update while you are doing a lengthy process you'll *have* to use threads. They're really not that hard - especially if you use the BackgroundWorker class to control it for you. – ChrisF Jun 18 '10 at 11:07
  • Like ChrisF says, its better with threads. Not using them will keep you inexperienced. – GvS Jun 18 '10 at 11:58
  • I guess you are right. Thank you everyone for helping me out. – Rabin Jun 20 '10 at 04:23
0

Use the gif in a PictureBox, and have it open using Form pWait = new Form(); pWait.Show();

Danny Beckett
  • 20,529
  • 24
  • 107
  • 134