ConcurrentDictionary GetOrAdd is not atomic. Any alternatives besides blocking?

I use a parallel dictionary to store open files.

To open a new file, I do the following:

myDictionary.GetOrAdd (fName, (fn) => new StreamWriter(fn, true));

And with this, I regularly get the following exception:

System.IO.IOException: The process cannot access the file '....' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPa
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
   at System.IO.StreamWriter..ctor(String path, Boolean append)

For me, this means that the operation is not atomic and that the software is trying to open the same file twice.

Is it possible to use another operation that will be atomic? I want to avoid blocking for performance reasons.

+3
source share
3 answers

, , , / , ConcurrentDictionary<string, Lazy<StreamWriter>>, factory Lazy<StreamWriter>, LazyThreadSafetyMode.ExecutionAndPublication ( , ). , , .

private static ConcurrentDictionary<string, Lazy<StreamWriter>> _myDictionary =
    new ConcurrentDictionary<string, Lazy<StreamWriter>>();

public static StreamWriter GetOrCreate(string fName)
{
    return _myDictionary.GetOrAdd(fName,
        new Lazy<StreamWriter>(() => new StreamWriter(fName),
            LazyThreadSafetyMode.ExecutionAndPublication)).Value;
}
+4

. , , , . , .

, ConcurrentDictionary ReadWriterLockSlim. ( ), . , , , , - .

+3

factory, , , . , ConcurrentDictionary .

:

GetOrAdd , addValueFactory , / ​​ .

http://msdn.microsoft.com/en-us/library/ee378677(v=vs.110).aspx

+1

All Articles