How to make objects Threadsafe on c#?

后端 未结 3 511
灰色年华
灰色年华 2021-01-07 06:30

I have a an application that requires threading in most cases. Most of the time I will encounter errors or wrong values because the object was updated prior to its execution

相关标签:
3条回答
  • 2021-01-07 07:01

    Start here: Synchronizing Data for Multithreading

    Basically, you'll need to use a mutex. In .NET every object can act as a mutex, so you can use the lock keyword on any object to ensure mutual exclusions.

    0 讨论(0)
  • 2021-01-07 07:10

    Look into using the lock statement for any resources that you need to make thread safe.

    http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

    class Account
    {
        decimal balance;
        private Object thisLock = new Object();
    
        public void Withdraw(decimal amount)
        {
            lock (thisLock)
            {
                if (amount > balance)
                {
                    throw new Exception("Insufficient funds");
                }
                balance -= amount;
            }
        }
    }
    

    This would be my first step. Also you can look into the Monitor class.

    http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx

    These are the two basic ways that you can protect your resources during concurrent operations. There are many other ways such as mutexes, sempahores, conditional read/write locks,etc.

    0 讨论(0)
  • 2021-01-07 07:21

    The first thing you should do is draw a Happens-Before graph of the problem you want to solve by multi-threading. If you can't draw your design, it's too complicated.

    For example, this is a happens-before graph of a method which takes two arrays of ints and outputs the sum of all elements.

    enter image description here

    Once you have your happens-before graph it is really easy to see what has to happen before something else, but more importantly it shows you what does not have to happen before something else.

    In this example, you can get the sums of both array1 and array2 at the same time. You can also get sum1 at the same time as sum2 since they don't depend on each other. Adding the sums to TotalSum1 can be done in either order, (but you will need to lock around the addition step since you can't do the addition at the same time as another).

    C# .net 4.0 has a lot of useful capabilities for parallel programming.

    I recommend this book Parallel Programming with Microsoft .Net -- just use the bookmarks on the left to navigate it. It covers the parallel patterns of Loops, Tasks, Aggregation, Futures, and Pipelines.

    In the example above, I would use a Task1 to get the Array1 and Task2 to get the Array2, then within both of those I would use the Aggregation patterns built into a Parallel.For loop for the array sums, I would need to use locks or an Interlocked.Add to accumalate the subTotals, then wait for the tasks to finish and return the result.

    Useful Patterns:

    • Task
    • Parallel Loops
    • Producer/Consumer
    • Pipeline
    • Worklist
    • MapReduce

    Useful Tools:

    • Task Parallel Library
      • Parallel.For
      • Parallel.Foreach,
      • Tasks
    • PLinq
    • Concurrent DataStructures
      • ConcurrentQueue
      • etc.
    • Locking
      • 'lock' keyword
      • Monitor (same functionality as 'lock')
      • Semaphores
      • Spinlocks
      • Read/Write locks
    • Hardware Atomic Operations
      • Interlocked.Increment
      • Interlocked.Add
      • Interlocked.CompareAndSwap
      • Assignments to machine word length variables like int
    • Message Passing
      • MPI
      • Barriers
      • etc.

    Basically, understand your problem first then choose the tools/patterns to solve it.

    0 讨论(0)
提交回复
热议问题