1

Hello I have two methods which work on the same data. Method LoadData() loads/reloads data in memory from file and it is called very rarely (only when files are updated). Method GetData() gets data from memory and it is called from many different threads very often.

I want to achieve following behavior:

When execution of LoadData() begins, block new threads which tries to execute GetData(), then wait until threads, which currently executes GetData() to finish its execution, then continue execute LoadData() and when it is finished unblock the threads which previously were blocked. That's it.

private Object _LoadDataLock;
public void LoadData()
     lock (_LoadDataLock) {
     {
          // (1.) Block new executions of GetData();
          // (2.) Wait threads currently executing GetData() to complete its execution.

          // (3.) Do some work ..... Loading from files.

          // (4.) Unblock blocked in (1.) threads.
     }
}

public IDictionary GetData(string key1, string key2)
{
    //Do something....
    retrn data;
}

How can I achieve that behavior using C#?

Thanks. Ivan

ihmgsm
  • 23
  • 6
  • 2
    You should be familiar with synchronization. read all 5 parts of article in [link](http://www.albahari.com/threading/) carefully. –  Sep 15 '19 at 17:54
  • Try this approach https://stackoverflow.com/questions/54690274/c-volatile-reads-and-writes-of-hashset – mtkachenko Sep 15 '19 at 17:55
  • @ Farhad Mehrad Thank You the article is very informative. – ihmgsm Sep 15 '19 at 19:55

2 Answers2

2

This sounds like a good case for the ReaderWriterLock, which allow a single writer but multiple readers.

private ReaderWriterLock _lock;

public void LoadData()
{
    _lock.AcquireWriterLock();
    try
    {
         // Do some work ..... Loading from files.
    }
    finally
    {
        _lock.ReleaseWriterLock()
    }
}

public IDictionary GetData(string key1, string key2)
{
    _lock.AcquireReaderLock();
    try
    {
        //Do something....
        return data;
    }
    finally
    {
        _lock.ReleaseReaderLock()
    }
}
ESG
  • 8,988
  • 3
  • 35
  • 52
1

You need a mutual-exclusion surrounding the call of your method. The mutual-exclusion is targeting a certain object. Therefor you need to use the same object x within your expression statement.

You can use Lock with a code block:

   lock (x)
   {
       // Your code...
   }

or if you don't want to use a code block you can use Monitor:

    Monitor.Enter(x);
          // Your code...
    Monitor.Exit(x);
Felix Quehl
  • 744
  • 1
  • 9
  • 24