2

I need to load each second (or two) new image.

Following code doesn't work:

System.Threading.Thread.Sleep(2000);
this.Image_LoadImage.Source = new BitmapImage(new Uri(@"D:\\connect2-1.gif"));
System.Threading.Thread.Sleep(2000);
this.Image_LoadImage.Source = new BitmapImage(new Uri(@"D:\\connect3-1.gif"));

What I see is that the app sleeps for 4 seconds and then the second image appears.

How can i do it? Thanks.

vgru
  • 49,838
  • 16
  • 120
  • 201
N.D
  • 1,009
  • 5
  • 23
  • 39

4 Answers4

5

Use a timer.

Calling thread sleep is gonna block the UI thread. Found this link for you:

EKS
  • 5,543
  • 6
  • 44
  • 60
5

Use timer for this

    private System.Threading.Timer timer;
    public MainWindow()
    {
        InitializeComponent();
        timer = new System.Threading.Timer(OnTimerEllapsed, new object(), 0, 2000);
    }

    private void OnTimerEllapsed(object state)
    {
        if (!this.Dispatcher.CheckAccess())
        {
            this.Dispatcher.Invoke(new Action(LoadImages));
        }
    }

    private bool switcher;
    private void LoadImages()
    {
        string stringUri = switcher ? @"D:\\connect2-1.gif" :
                                      @"D:\\connect3-1.gif";
        this.Image_LoadImage.Source = new BitmapImage(new Uri(stringUri));

        switcher = !switcher;
    }
Stecya
  • 22,896
  • 10
  • 72
  • 102
  • when i use a timer and in the OnTimerEllapsed i try to change the images source , i get an exception which says that it cannot access the image because it's owned by another thread.... @Stecya – N.D May 03 '11 at 12:25
  • @olia, please see my answer about the correct thread-safe usage of Timers when updating the UI in a .Net application. – magma May 03 '11 at 12:26
  • @olia - You need to switch to main thread in order to work with UI elements, Please see my edit – Stecya May 03 '11 at 12:30
  • @Stecya , thanks. i declared a delegate wich points to the LoadImages and it works, but the problem is that i still see the second image .... Like @magma wrote in his answer ... – N.D May 03 '11 at 12:55
  • @olia - please see my edit.This will switch images every 2 seconds – Stecya May 03 '11 at 13:14
3

I suppose that your code resides in a single function, which executes on the main thread. For this reason, the UI will not be updated until your function returns.

At that point, you'll be left with whatever state was the latest at the time your function returned (this is why you're only seeing the last picture you've set).

Also, note that by issuing a Sleep() request mid-function, you're essentially blocking the main thread of your application (or whatever thread your function is running in, but it's likely that this is your main thread). During sleep time, your application won't simply respond to anything and your UI will freeze.

You might decide to invalidate your controls (Control.Refresh(), Control.Invalidate(), Control.Update(), Control.Refresh(), Application.DoEvents()) but these are generally hacks unless used properly.

Using a Timer is an option. Although, in your specific case, simply using an Animated GIF might be the best solution.

Note that if you decide to use a timer there is quite an important difference between System.Windows.Forms.Timer and other timers. System.Windows.Forms.Timer will run on your main thread at the earliest convenience (and so, it will be safe to interact with UI controls because you will be doing so from the same thread; but, on the other hand, it might fire with a slight delay). If, instead, you're going to use a different timer, you will not be able to access UI controls directly without violating an important rule. More about that here: Comparing the Timer Classes in the .NET Framework Class Library

See: Force GUI update from UI Thread

And: Animated Gif in form using C#

Community
  • 1
  • 1
magma
  • 8,432
  • 1
  • 35
  • 33
0

Try to refresh() your control after you change it's source.

atoMerz
  • 7,534
  • 16
  • 61
  • 101
  • As magma said, using Refresh() or DoEvents() is almost always a hack when used for this purpose. – Shibumi May 03 '11 at 14:48
  • 1
    @Shyibumi, why? I'm sure I read it in a book. can you explain? – atoMerz May 03 '11 at 18:40
  • Off the top of my head: Refresh can actually cause a lot of repainting work to be done up and down the control hierarchy. It's better to allow controls to paint on their own when possible. DoEvents will cause all events in the queue to be handled and all of their handlers' code to be run, not just yours. Unless there's a good reason, the threading with callback method is almost always the best way to go. – Shibumi May 24 '11 at 21:19