15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

534 ❘ ChaPTer 20 threAds, tAsks, And synchrOnizAtiOn<br />

If the time interval should be changed after creating the Timer object, you can pass new values with the<br />

Change() method.<br />

private static void ThreadingTimer()<br />

{<br />

var t1 = new System.Threading.Timer(<br />

TimeAction, null, TimeSpan.FromSeconds(2),<br />

TimeSpan.FromSeconds(3));<br />

Thread.Sleep(15000);<br />

}<br />

t1.Dispose();<br />

static void TimeAction(object o)<br />

{<br />

Console.WriteLine("System.Threading.Timer {0:T}", DateTime.Now);<br />

}<br />

code snippet TimerSample/Program.cs<br />

The constructor of the Timer class from the System.Timers namespace requires just a time interval. The<br />

method that should be invoked after the interval is specified by the Elapsed event. This event requires a<br />

delegate of type ElapsedEventH<strong>and</strong>ler, which requires object <strong>and</strong> ElapsedEventArgs parameters, as you<br />

can see with the TimeAction method. The AutoReset property specifies whether the timer should be fired<br />

repeatedly. If you set this property to false, the event is fired only once. Calling the Start method enables<br />

the timer to fire the events. Instead of calling the Start method, you can set the Enabled property to true.<br />

Behind the scenes Start() does nothing else. The Stop() method sets the Enabled property to false to<br />

stop the timer.<br />

private static void TimersTimer()<br />

{<br />

var t1 = new System.Timers.Timer(1000);<br />

t1.AutoReset = true;<br />

t1.Elapsed += TimeAction;<br />

t1.Start();<br />

Thread.Sleep(10000);<br />

t1.Stop();<br />

}<br />

t1.Dispose();<br />

static void TimeAction(object sender, System.Timers.ElapsedEventArgs e)<br />

{<br />

Console.WriteLine("System.Timers.Timer {0:T}", e.SignalTime );<br />

}<br />

eVenT-based asynChronous PaTTern<br />

Earlier in this chapter, you saw the asynchronous pattern based on the IAsyncResult interface. With an<br />

asynchronous callback, the callback thread is different from the calling thread. Using Windows Forms or<br />

WPF, this is a problem, because Windows Forms <strong>and</strong> WPF controls are bound to a single thread. With every<br />

control, you can invoke methods only from the thread that created the control. This also means that if you<br />

have a background thread, you cannot directly access the UI controls from this thread.<br />

The only methods with Windows Forms controls that you can invoke from a different thread than the creator<br />

thread are Invoke(), BeginInvoke(), EndInvoke(), <strong>and</strong> the property InvokeRequired. BeginInvoke()<br />

<strong>and</strong> EndInvoke() are asynchronous variants of Invoke(). These methods switch to the creator thread to<br />

invoke the method that is assigned to a delegate parameter that you can pass to these methods. Using these<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!