Card Set Information

2011-09-28 14:00:13
Sharp Programming Threads Threading Mutex Semaphore STA

Questions around Threading in C#
Show Answers:

  1. What is STA?
    Single Threaded Apartment
  2. [C# 4.0 in a Nutshell, pg 792]
    Given the following multi-threaded sequence:
    var t = new Thread(WriteY);
    Console.WriteLine("Thread t has ended");
    What does the Join method do?
    Waits for Thread t to finish before printing the "ended" statement
  3. [C# 4.0 in a Nutshell, pg 793]
    What does the newly introduced in Framework 4.0 function Thread.Yield() do?
    Similar to Thread.Sleep(), it relinquishes the thread's current time slice, handing the CPU to other threads, except Yield only relinquishes to threads running on the same processor.
  4. [C# 4.0 in a Nutshell, pg 794]
    Given the following Thread code:
    var t = new Thread(Print)
    t.Start("Hello from t");
    Implement the Print function so that it prints the string to the Console.
    • void Print(object msgObj)
    • {
    • var msg = (string) msgObj;
    • Console.WriteLine(msg);
    • }
  5. [C# 4.0 in a Nutshell, pg 794]
    What happens when running the following:
    for (int i = 0; i < 10; i++)
    new Thread(() => Console.Write(i)).Start();
    • Since the i variable refers to memory who's value may change as each thread is running, the output is nondeterministic. So it prints unexpected output, e.g., 223456789.
    • The solution would be to use a temporary variable.
  6. [C# 4.0 in a Nutshell, pg 795]
    What approach to sharing data between threads is more common than captured variables?
    Use fields
  7. [C# 4.0 in a Nutshell, pg 795]
    Given the following class:
    class Introducer {
    public string Message; public string Reply;
    public void Run() {
    Reply = "Hi right back at you";}}
    Write multi-threaded code that runs the Run() method.
    • var intro = new Introducer();
    • intro.Message = "Hello";
    • var t = new Thread(intro.Run);t.Start();
    • t.Join();Console.WriteLine(intro.Reply);
  8. [C# 4.0 in a Nutshell, pg 798]
    What's wrong with this code?
    try { new Thread(Go).Start(); }
    catch (Exception e) { Write("Exception!"); }
    void Go() { throw null; }
    What could be done to address it?
    • Since each thread has an independent execution path, the try...catch never happens because the Exception stays with the thread that threw it.
    • Move the exception handling to the Go method
  9. [C# 4.0 in a Nutshell, pg 800]
    What are some ways to enter the thread pool (up to four)?
    • Via the Task Parallel Library or PLINQ(Framework 4.0)
    • By calling ThreadPool.QueueUserWorkItem
    • Via asynchronous delegates
    • Via BackgroundWorker
  10. [C# 4.0 in a Nutshell, pg 800]
    Which constructs use the thread pool indirectly (up to three)?
    • WCF, Remoting, ASP.NET, ASMX Web Services application servers
    • System.Timers.Timer and System.Threading.Timer
    • Framework methods ending in Async and most BeginXXX methods
  11. [C# 4.0 in a Nutshell, pg 801]
    How would you find out if you're currently executing on a pooled thread?
    • Query the property:
    • Thread.CurrentThread.IsThreadPoolThread
  12. [C# 4.0 in a Nutshell, pg 803]
    What is missing from this code?
    static void Go() {
    ("Hello from the thread pool!");}
    • QueueUserWorkItem expects at least one parameter for the callback.
    • The fix is to change Go to take an object:
    • static void Go(object data)
  13. [C# 4.0 in a Nutshell, pg 804]
    In the following code, what does EndInvoke do (three things)?
    Func<string, int> method = Work;
    var cookie = method.BeginInvoke("test", null, null);
    int result = method.EndInvoke(cookie);
    Console.WriteLine("length: {1}", result);
    static int Work(string str) { return str.Length; }
    • Waits for the asynchronous delegate to finish if it hasn't already
    • Receives the return value (including ref or out)
    • Throws any unhandled worker exceptions back to the calling thread.
  14. [C# 4.0 in a Nutshell, pg 804]
    Fill in the arguments for BeginInvoke to have Done get called automatically upon completion.
    Func<string, int> method = Work;
    var cookie = method.BeginInvoke(?, ?, ?);
    static void Done(IAsyncResult asyncResult) {
    var target = (Func<string, int>) asyncResult.AsyncState;
    int result = target.EndInvoke(asyncResult);
    Console.WriteLine("Length is : {0}", result);}
    "test string", Done, method
  15. [C# 4.0 in a Nutshell, pg 805]
    What four categories to synchronization constructs fall into?
    • Simple blocking methods (e.g., Sleep, Join, Task.Wait)
    • Exclusive Locking (e.g., lock, Mutex, and SpinLock)
    • Nonexclusive Locking (e.g., Semaphore, SemaphoreSlim)
    • Signaling (e.g., Wait/Pulse, or CountdownEvent and Barrier (Framework 4.0))
    • Nonblocking (e.g., Thread.MemoryBarrier, Thread.VolatileRead, Interlocked class)
  16. [C# 4.0 in a Nutshell, pg 807]
    What is the caveat when querying ThreadState?
    public static ThreadState SimpleThreadState (ThreadState ts) {
    return ts & (ThreadState.Unstarted| ThreadState.WaitSleepJoin| ThreadState.Stopped);}
    While it's useful for diagnotic purposes, it's not meant for synchronization since a thread's state may change before the information can be acted upon.
  17. [C# 4.0 in a Nutshell, pg 817]
    When is a program or method considered thread-safe?
    True of False: Most .NET Framework types, when instantiated, are thread-safe for anything more than concurrent read-only access.
    • When it has no indeterminancy in the face of any multithreaded scenario.
    • False. Few .NET Framework types are thread-safe under these conditions (with the exception of System.Collections.Concurrent).
  18. [C# 4.0 in a Nutshell, pg 809]
    Is the following class thread safe? Why not?
    class ThreadUnsafe {
    static int _val1 = 1, _val2 = 1;
    static void Go() {
    if (_val2 != 0)
    Console.WriteLine(_val1 / _val2);
    _val2 = 0; }
    • It's unsafe because _val2 could be set to zero in one thread while another thread was in between the if and WriteLine statements.
    • A solution would be to introduce object _locker
    • and change Go to be:
    • lock(_locker)
    • { put the same code here }
  19. [C# 4.0 in a Nutshell, pg 813]
    What is deadlock? What is one way to avoiding it?
    • In terms of threading, it's when two threads each wait for a resource help by the other so neither can proceed.
    • Be wary of locking around calling methods in objects that may have references back to your own object.
    • When you call out to other code while holdling a lock, the encapsulation of the lock subtly leaks.
  20. [C# 4.0 in a Nutshell, pg 815]
    Compare Mutex and lock.
    • Mutex can work across multiple processes.
    • Acquiring and releasing an uncontended Mutex is about 50 times slower than a lock (a few microseconds vs 100 nanoseconds)
  21. [C# 4.0 in a Nutshell, pg 816]
    What is a Semaphore? How can it be useful?
    • A semaphore enforces a specified capacity. A semaphore with a capacity of one is similar to a Mutex or lock except the semaphore has no "owner" (it's thread-agnostic). Any thread can call Release on a Semaphore.
    • They can be used to limit concurrency so there doesn't become too many threads executing a particular piece of code.
  22. [C# 4.0 in a Nutshell, pg 817]
    In the following code, what does the Wait() method do?
    static SemaphoreSlim _sem =
    new SemaphoreSlim(3);
    foreach (var i in Enumerable.Range(1, 5))
    new Thread(Enter).Start(i);
    static void Enter (object id) {
    Console.WriteLine(id + " wants to enter");
    Console.WriteLine(id + " is in!");
    Thread.Sleep(1000 * (int)id);
    Console.WriteLine(id + " is leaving");
    _sem.Release(); }
    Blocks the current thread until it can enter
  23. [C# 4.0 in a Nutshell, pg 818]
    What are the benefits of stateless design, which are usually implemented in middle-tier applications and web servers?
    It intrinsically limits the possibility of interaction, since classes do not persist data between requests.
  24. [C# 4.0 in a Nutshell, pg 820]
    True or False. In the .Net Framework, instance members are thread safe, static members are not.
    False. The opposite is true.
  25. [C# 4.0 in a Nutshell, pg 822]
    What is thread affinity?
    Objects with thread affinity means that only the thread that instantiates them can subsequently access their members.
  26. [C# 4.0 in a Nutshell, pg 822]
    What would you need to do in order to access an object X with thread affinity created on another thread Y?
    • You would need to marshal the request to thread Y.
    • In WPF, call Invoke or BeginInvoke on the element's Dispatcher object
    • In Windows Forms, call Invoke or BeginInvoke on the control.
  27. [C# 4.0 in a Nutshell, pg 823]
    What two categories of threads do Rich Clients typically employ?
    UI threads and worker threads. Usually, one UI thread might spawn worker threads. Except in the case of a Single Document Interface (SDI), which can have multiple UI threads.
  28. [C# 4.0 in a Nutshell, pg 823]
    What are Immutable Objects useful for?
    They're valuable in multithreading by avoiding the problem of shared writeable state, by eliminating or minimizing the writable.
  29. [C# 4.0 in a Nutshell, pg 823]
    Given the following class and instance objects of it, implement ReadStatus and UpdateStatus using locking:
    class ProgressStatus{
    public readonly int PercentComplete;
    public readonly string StatusMessage;
    public ProgressStatus
    (int percentComplete, string statusMessage){PercentComplete = percentComplete;
    StatusMessage = statusMessage;}}
    static readonly object _statusLocker =
    new object();
    static ProgressStatus _status;
    • private static void UpdateStatus
    • (ProgressStatus progressStatus){
    • lock (_statusLocker) _status = progressStatus;}

    • private static ProgressStatus ReadStatus(){ProgressStatus status;
    • lock(_statusLocker) status = _status;
    • return status;}
  30. [C# 4.0 in a Nutshell, pg 828]
    What does the keyword volatile mean?
    Instructs the compiler to generate an acquire-fence on every read from the designated field, and a release-fence on every write to it.