Sync Object vs Invoke

In my form class, I added a fade method. This uses System.Timers.Timerand the event Elapseduses the delegate to change the opacity of the form. This was the code:

public void FadeOut()
{
    // Timer for transition
    Timer fade = new Timer();

    // Transition code
    fade.Elapsed += delegate
    {
        this.Opacity += 0.05;

        if (this.Opacity >= .95)
        {
            this.Opacity = 1;
            fade.Enabled = false;
            fade.Dispose();
        }
    };

    fade.Interval = 100;
    fade.Enabled = true;
}

This caused the “Continuous Cross Flow Operation” error, which is a common obstacle that I see. Therefore, I looked around the sides of the solutions and first came to the conclusion, using .BeginInvokecode blocks to support the call in the same thread as the control. But I found that it looks very bulky, so I continued to search, and then discovered a property SynchronizingObject System.Timers.Timer. This seems better, because it needs only one extra line of code:

// Timer for transition
Timer fade = new Timer();
fade.SynchronizingObject = this;

. , BeginInvoke/Invoke, , , - SynchronizingObject ?

+3
5

, , Invoke BeginInvoke, SynchronizingObject.

, ; .

, , Reflector MyTimerCallback private member System.Timers.Timer:

 ElapsedEventHandler onIntervalElapsed = this.onIntervalElapsed;
 if (onIntervalElapsed != null)
 {
     if ((this.SynchronizingObject != null) && this.SynchronizingObject.InvokeRequired)
     {
         this.SynchronizingObject.BeginInvoke(onIntervalElapsed, new object[] { this, e });
     }
     else
     {
         onIntervalElapsed(this, e);
     }
 }
+2

, . , , Elapsed . , System.Windows.Forms.Timer.

, . , Elapsed . TP, . , .

System.Windows.Forms.Timer. threadpool.

+3

WinForms? ; , , ( /).

+1

.

BeginInvoke SynchronizationContext.

, , , , .

0

- SCOPE . ? .

timer.SynchronizingObject . 'this' Form1, , "Form1", . . .

, , - , Form1, , Windows. .

, , . , . . . . Visual Studio . . , . .

The important part here is that only a few lines of code are redirected to run on the Form1 stream. Not the entire event handler. Most of the event processing code runs in another thread. And this includes code, for example, to do something on the network or on disk.

It makes a DIFFERENCE.

BUT, all this applies only to applications with windows. For WPF, just use a dispatch timer. (This is why you cannot find Windows.Threading in WinForm, because you cannot use the dispatch timer in WinForm, but are available in WPF)

0
source

Source: https://habr.com/ru/post/1788969/


All Articles