1

I have an application that has many threads, where each thread performs some operation on a resource that is referenced by a GUID, where said GUID is stored in a list as strings. Only one operation can occur on the resource referenced by the GUID at any time.

I'm trying to use lock statements for this and a simple List. The problem I'm running into is that I can't seem to safely put the check to see if the list contains the GUID inside a lock statement, and then follow it with another lock statement to add it to the list. It seems that when there are multiple threads, each checking to see if that GUID is in the list, and the check returns false for both, they both add the GUID (obvious problem).

Also, I can't put the check inside the same lock as the statement to add the GUID to the string list, because if I do, the lock will be held, preventing other threads that are working on the resource from removing it from the list (they can't get the lock).

I hope you'll forgive my primitive example, but I can't figure out how to reliably test and lock safely in a multi-threaded environment. I'm not at liberty to change the design of the app for my client, either, unfortunately.

If you have a class/library to recommend, a small example would be most appreciated.

private static readonly object _guidLock = new object();
private static List<string> guidList = new List<string>();

public static bool isGuidLocked(string guid)
{
    lock (_guidLock)
    {
        if (guidList.Contains(guid)) return true;
        return false;
    }
}

public static bool lockGuid(string guid)
{
    while (isGuidLocked(guid)) { }
    lock (_guidLock)
    {
        guidList.Add(guid);
    }
    return true;
}

public static bool releaseGuid(string guid)
{
    lock (_guidLock)
    {
        guidList.Remove(guid);
    }
    return true;
}

public static void doWorkOnGuid(string guid)
{
    lockGuid(guid);
    // do something there
    releaseGuid(guid);
}
2
  • Are you looking for correct approach or explanation why your code is unlikely to work correctly? (You probably want look into "double checked locking" to see how it could be done to get your code working correctly) Commented Jan 4, 2016 at 4:50
  • I'd love to understand the correct approach better to see if I can integrate it correctly. Commented Jan 4, 2016 at 4:58

2 Answers 2

4

Don't use a List. .NET provides thread-safe collections.

In this case you probably want ConcurrentDictionary using the GUID as the key.

See namespace: System.Collections.Concurrent

The System.Collections.Concurrent namespace provides several thread-safe collection classes that should be used in place of the corresponding types in the System.Collections and System.Collections.Generic namespaces whenever multiple threads are accessing the collection concurrently.

Sign up to request clarification or add additional context in comments.

4 Comments

Example how I handle the "wait and add" case in 'lockGuid' above?
You don't need to manually wait. I think you want the TryAdd() method on ConcurrentDictionary. It will return true if the GUID didn't already exist and was added, otherwise false.
i.e. while (!TryAdd(...)) { } would do what I need?
Yeah that'll do it. Just keep in mind that indefinitely blocking code could be hazardous. You may also want a small Thread.Sleep so it doesn't hammer the dictionary as fast as it can until able to add.
0

Use time stamp based concurrency control techniques for such situations. Use one static variable _guidListUpdateTime which will hold the latest _guidList modifying time. Similarly, assign a readtime stamp value to each thread. Now while adding the guid to list check whether the current thread readtime stamp is greater than the _guidListUpdateTime or not. If yes, then add the guid to guidList otherwise not. https://www.classle.net/book/timestamp-based-protocol

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.