Presentation is loading. Please wait.

Presentation is loading. Please wait.

Multithreading .NET a practical perspective

Similar presentations


Presentation on theme: "Multithreading .NET a practical perspective"— Presentation transcript:

1 Multithreading .NET a practical perspective
7/5/2018 Multithreading .NET a practical perspective Peter Ibbotson

2 7/5/2018 Why multi-thread? With new dual core processors makes better use of the CPU Keeps the User Interface responsive during long calculations. Allows Asynchrous IO - Asynchronous Programming model (aka APM) Single CPU systems can be slightly slower, but the user experience is better.

3 Why not multi-thread? It's hard to do right. Really it is!
7/5/2018 Why not multi-thread? It's hard to do right. Really it is! Generates Heisenbugs very easily Synchronisation is hard Often you don't really need it Talking to Windows forms controls is tricky Threads aren't cheap

4 Thread basics I Threads aren't "free"
7/5/2018 Thread basics I Threads aren't "free" They get 1MB of address reserved for stack + 12KB of kernel-mode stack Each DLL in the parent process gets called to say a new thread has been created Each DLL also gets called when a thread is about to die. Context switches save / restore registers (700 bytes on x86, 1240 on x64) and use a spinlock so take time.

5 7/5/2018 Thread basics II Create a tread using ThreadStart passing in a delegate to call: Thread Worker=new Thread(new ThreadStart(StartMethod)); Start the thread using Thread.Start(); Stop a thread using Thread.Abort() Suspend a thread using Thread.Suspend(); Wait for a thread to complete using Thread.Join();

6 7/5/2018 Example Notes Parameterised threads aren't always a good idea particularly as they aren't type safe. Often better to create a whole class with local variables that you initialise before you start the thread.

7 7/5/2018 Variables and caches Two threads share variables BUT the cache gets in the way. Each one may not see the same value. internal sealed class CacheCoherencyProblem { private byte m_init=0; private Int32 m_value=0; public void Thread1(){ m_value=5; m_init=1;} public void Thread2(){ if (m_init==1) WriteLine(m_value);} } In theory if you run this it may display 0, but this depends on cachelines

8 Variables and caches step 1
7/5/2018 Variables and caches step 1 CPU1 runs Thread1 CPU2 Thread2 internal sealed class CacheCoherencyProblem { private byte m_init=0; private Int32 m_value=0; public void Thread1(){ m_value=5; m_init=1;} public void Thread2(){ if (m_init==1) WriteLine(m_value);} } CPU2 reads a byte from memory and it's before m_value fields bytes in memory, so both of them get read into cache. So CPU2 has m_value already in cache

9 Variables and caches step 2
7/5/2018 Variables and caches step 2 CPU1 runs Thread1 CPU2 Thread2 internal sealed class CacheCoherencyProblem { private byte m_init=0; private Int32 m_value=0; public void Thread1(){ m_value=5; m_init=1;} public void Thread2(){ if (m_init==1) WriteLine(m_value);} } CPU1 runs Thread1 and changes m_value to 5 but this stays in cache, the following m_init=1 line gets written straight out to main memory

10 Variables and caches step 3
7/5/2018 Variables and caches step 3 CPU1 runs Thread1 CPU2 Thread2 internal sealed class CacheCoherencyProblem { private byte m_init=0; private Int32 m_value=0; public void Thread1(){ m_value=5; m_init=1;} public void Thread2(){ if (m_init==1) WriteLine(m_value);} } Now CPU2 reads in m_init sees it's set to 1 and reuses the m_value from cache so m_value contains 0 and that is whats displayed

11 Sorry No demonstration
7/5/2018 Sorry No demonstration Sadly I couldn't get something like this to fail reliably There are work arounds Use VolatileRead & Write Better yet use the C# keyword volatile. Or just ignore it and use either System.Threading.Interlocked Monitor class and C# lock

12 The better idea use the monitor class
7/5/2018 The better idea use the monitor class Quick demo of the problem Example 2

13 The better idea use the monitor class
7/5/2018 The better idea use the monitor class Quick demo of the problem Example 2 Hopefully that race condition printed bingo a few times The solution is to use C# lock statement Back to the example

14 Monitor class and lock statement
7/5/2018 Monitor class and lock statement private void SomeMethod() { lock(this) { …. Access object } } Private void SomeMethod() { Object temp=this; Monitor.enter(temp); try { ….Access object } finally Monitor.Exit(temp); }

15 Using locks in the real world
7/5/2018 Using locks in the real world Don't do too many locks (Prefer locking larger objects) Beware of nesting too deeply Beware of deadlocking. Thread A acquires locks in this order Lock 1,2. Thread B acquires locks in this order Lock 2,1. On a bad day thread A has 1 locked and is waiting for 2 to become free. This will never happen as Thread B has lock 2 and is waiting for lock 1

16 7/5/2018 Reader writer locks ReaderWriterLock gives many readers access but only one writer. Vance Morrison has more on this from the performance point of view Use his version if performance is a problem from:

17 7/5/2018 Thread pool After all that don't create threads directly. They are quite expensive. Use System.Threading.Threadpool instead. The thread pool puts threads into two classes Compute bound IO bound It adds threads to the pool in 500ms increments – See example (3)

18 Asynchronous Programming Model
7/5/2018 Asynchronous Programming Model It's a pattern for doing asynchronous callbacks when something completes (i.e. network, file io etc) Always of the form BeginXxxx EndXxxx BeginRead / EndRead for files BeginConnect / EndConnect for sockets Etc… Always Call EndXxxx otherwise you'll leak The callback is on a ThreadPool thread. Time for an example (4)

19 Windows forms An alternative to multi-threading Use a modal dialog
7/5/2018 Windows forms An alternative to multi-threading Use a modal dialog Call DoEvents in loop while pooling the cancel button state. Quick example (5)

20 Windows forms some VB6 tricks revisited
7/5/2018 Windows forms some VB6 tricks revisited An alternative to multi-threading Use a modal dialog Call DoEvents in loop while pooling the cancel button state. Quick example (5) Other alternatives - use a WinForms timer and a state machine. The WinForms timer posts WM_TIMER messages on the main UI thread.

21 Sometimes even Microsoft go single threaded
7/5/2018 Sometimes even Microsoft go single threaded Version 6 of the animation control stopped using a background worker thread now uses WM_TIMER If the main window stops reading messages (DoEvents) there is a chance the animation control will stall trying to get the background colour If the foreground process doesn't read messages then if another window sends a broadcast message, windows stops but the animation keeps running. See

22 Windows forms and threads (Examples stolen from chris sells)
7/5/2018 Windows forms and threads (Examples stolen from chris sells) "Thou shalt not operate on a window from other than its creating thread” This means you need to use Invoke or BeginInvoke and EndInvoke These transfer control back to the UI thread. has a load of details Example 6 and 7

23 Windows forms and threads (Examples stolen from chris sells)
7/5/2018 Windows forms and threads (Examples stolen from chris sells) "Thou shalt not operate on a window from other than its creating thread” This means you need to use Invoke or BeginInvoke and EndInvoke These transfer control back to the UI thread. Adding a Cancel button Example 8

24 ComponentModel.BackgroundWorker
7/5/2018 ComponentModel.BackgroundWorker Use this for simple background tasks Simple to use and doesn't require BeginInvoke and friends

25 Multiple UI threads Useful for things like reports
7/5/2018 Multiple UI threads Useful for things like reports Use Application.Run from a new thread.

26 Further resources Chris Sells MSDN articles
7/5/2018 Further resources Chris Sells MSDN articles Jeffrey Richter – CLR via C# (book) Vance Morrison Invoke and friends has a load of details This powerpoint is at


Download ppt "Multithreading .NET a practical perspective"

Similar presentations


Ads by Google