0

I am developing an asp.net webapi project. a controller action method will check local files and download updated files if the locals get expired. Since this action may be requested by multiple clients at the same time, so I am afraid there will be file Concurrency issue.

in my downloadService class, I consider using ReaderWriterLock.

question 1: where should I init the ReaderWriterLock? should I keep it as a private member?

private readonly ReaderWriterLock asyncReaderWriterLock = new();

Or should I each time create it in the fileWrite method?

question 2: assume it's an instance member, if there're multiple downloadService objects, then there will be a lot of locks. will it still work?

does this lock file or code?

question 3: if there're 100 files, when I operate File A, it should not affect file B. which means, thread B can write File B at the same time when thread A writes file A. so do I need to assign 100 locks for these files?

Thanks

10120
  • 95
  • 8
  • 2
    The `ReaderWriterLock` doesn't know or care about the code it's guarding. It simply provides a gate. What you do once you've been allowed to pass through that gate is none of that object's concern. It's up to you to make sure that the correct code is behind the correct gate. In short, it doesn't lock your files so they are complete exposed to any code not behind the appropriate gate. – John May 06 '22 at 07:13
  • The point of a `ReaderWriterLock` is to allow multiple readers but only one writer. Do you care about readers at all? If not then this is probably not the class you need. Also, it protects a specific resource. If you have multiple resources to protect independently then you need multiple locks. – John May 06 '22 at 07:16
  • Is this a viable solution to your problem? [Enforce an async method to be called once](https://stackoverflow.com/questions/28340177/enforce-an-async-method-to-be-called-once) – Theodor Zoulias May 06 '22 at 07:16
  • Also, as [the documentation](https://learn.microsoft.com/en-au/dotnet/api/system.threading.readerwriterlock?view=net-6.0) clearly states, `ReaderWriterLockSlim` should be used in preference to `ReaderWriterLock`. – John May 06 '22 at 07:18

1 Answers1

1

where should I init the ReaderWriterLock?

You should initialize it in the class where it is used

should I keep it as a private member?

Yes, otherwise it is possible for some unrelated class to take the lock, and this increases the risk for deadlocks. A good practice for avoiding deadlocks is to only lock a small section of code and avoid raise any events or otherwise call arbitrary code while holding the lock.

Or should I each time create it in the fileWrite method?

The lock object should represent the resource that is being locked, and there should only be one lock object per resource. Creating a new object for each fileWrite would be counter productive since it would not offer any protection.

assume it's an instance member, if there're multiple downloadService objects, then there will be a lot of locks. will it still work?

Yes, you can have as many lock objects as you want.

does this lock file or code?

The lock object does not care about what is being protected. It just ensures that only a single thread can hold the lock at a time. What is being protected is up to you.

if there're 100 files, when I operate File A, it should not affect file B. which means, thread B can write File B at the same time when thread A writes file A. so do I need to assign 100 locks for these files?

If you want lock granularity at the file level, then you need one lock per file.

I would note that multi threaded programming is difficult. Threading errors tend to be spurious, difficult to reproduce and non obvious. Some of the rules about ordering just does not apply when multiple threads are involved. So I would encourage you to read a far bit about the topic and the hazards involved before doing anything important involving multiple threads.

JonasH
  • 28,608
  • 2
  • 10
  • 23
  • oh mysir can you recommend a good book about this topic? – 10120 May 06 '22 at 13:09
  • @10120 There are fairly many articles discussing thread safety. If you want somewhere to start I might recommend this article on [concurrency hazards](https://learn.microsoft.com/en-us/archive/msdn-magazine/2008/october/concurrency-hazards-solving-problems-in-your-multithreaded-code). [Threading best practices](https://learn.microsoft.com/en-us/dotnet/standard/threading/managed-threading-best-practices) might also be useful. – JonasH May 06 '22 at 13:44