Threading with Mutex

I have a console application which will process a number of folder paths and documents. The idea is that I want to start a thread for each path/file. Each of these paths will be created on a server using an API. for each folder created I need to get the guid for that folder

Once I process each path I'm adding them to a dictionary Dictionary<string, Guid>, so if I have the folder in the dictionary I don't need to call the api again.

The problem is when I start the threads they are all hitting the method at the same time. So if I have this string[] folders = { "/Folder 1/Folder 2", "/Folder 1" }; both threads are calling and trying to create Folder 1.

What I would like to do is something like this:
using (_lockThis.GetLock(folderPath)) {
                    Guid folderGuid = DirectoryRecursively(folderPath);

Open in new window

How could I obtain a lock so I an process the folder path and record the returned guid.

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

hjgodeTier 3 Senior Technical Support EngineerCommented:
I would use a global lock inside the DirectoryRecursively() function. The function will then block if another call is in progress. Inside the lock the function should then check first if the dir already exists (done by another call).

Possibly you can show your DirectoryRecursively() function to get a detailed advice.
WebfortAuthor Commented:
I use a dictionary to check if the directory exists. The problem is, say two threads start off in the example outlined. Both hit the method at the same time so both try and create Folder 1,  which then causes problems with the dictionary as they both try and add an item with the same key.

Check if incoming folder path exists in dictionary. return guid if it does
loop through the individual folders
Check if individual folder exists.
if it does not exist call api get guid add to dictionary and return value.

thanks in advance
WebfortAuthor Commented:
Also the reason I'm looking at mutex is this code could run across multiple processes. This looks like something I could adapt, but need a little help. I was looking to use a unique id/folder path for that user running the process?
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

WebfortAuthor Commented:
I think a combination of the above and this would work
hjgodeTier 3 Senior Technical Support EngineerCommented:
Sorry, but your code posts and links do not show how to approach your issue.

Example: you try to start two threads with \Dir1\Dir2 and \Dir1; thread 1 tries to create Dir1 and then Dir2, thread2 try to create Dir1. Now you need a lock for creating Dir1. If that is in thread 1 it will lock thread 2. Then Dir1 is created and thread2 starts to create Dir1, but it already exists. what I mean is you need a lock on a specific path (like /Dir1 or /Dir1/Dir2). A lock on the last dir component would not make sense, ie you can have Dir1/Dir2 und Dir1/Dir3 and would use a lock on Dir2 and Dir3.

So if you lock during any dir creation that would make your multithreading obsolete, if creating a dir is the only task inside the thread. But if you then have maultiple tasks (like Document creations etc) inside the sub dir, that would be a task to place inside a separate thread.

A lock (mutex) can asure that only one thread performs a specific task on a shared object. If you have multiple non-shared objects, like individual path, a lock makes no sense.

So, what about creating the dirs in one thread and then start separate threads to perform the tasks inside the individual dirs?
WebfortAuthor Commented:
Thanks, that makes sense. It would make the multi threading obsolete.

So create all  my directory structure in one thread, and then the files could be put into multiple threads? I guess I would then need to map file to the folder id so i can perform my uploads. Or like you say once I have created my dir upload my files and then move on to create the other folders?
hjgodeTier 3 Senior Technical Support EngineerCommented:
"So create all  my directory structure in one thread, and then the files could be put into multiple threads?"
Yes, and for each directory created that needs files put there start a thread to do so and the code will continue in creating new dirs.

pseudo code:
  create dir
  if dir has to get files->create thread with arg for dir and files
goto start

  will copy the files in background

with the above you do not need a mutex. Possibly you may use a ThreadPool where the threads are put in and started and executed by the system if there are free slots. The results will then delivered async.
your first idea is also valid. instead of locking a path you can lock directory creation like that:

public class MyFolder
    private string folderPath;
    private static object LockingVar = new object();
    public MyFolder(string path) 
          folderPath = path;
    public bool CreateFolderIfNotExists()
      lock (LockingVar)
         // check whether the folder exists. if not create the folder
      return true;

Open in new window


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
WebfortAuthor Commented:
Thanks, I now lock the directory creation. Thanks for all your help.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.