2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.Diagnostics.Contracts;
9 public enum NetworkOperation
16 //The NetworkGate prevents starting download/uploads for files that are already in the process of downloading,
18 public class NetworkGate:IDisposable
20 //The state of each file is stored in a thread-safe dictionary
21 static readonly ConcurrentDictionary<string, NetworkOperation> NetworkState = new ConcurrentDictionary<string, NetworkOperation>();
23 public static NetworkOperation GetNetworkState(string path)
25 if (String.IsNullOrWhiteSpace(path))
26 throw new ArgumentNullException("path");
27 if (!Path.IsPathRooted(path))
28 throw new ArgumentException("path must be a rooted path", "path");
29 Contract.EndContractBlock();
31 NetworkOperation operation;
32 if (NetworkState.TryGetValue(path.ToLower(), out operation))
34 return NetworkOperation.None;
37 //Store a network operation for the specified path
38 public static void SetNetworkState(string path, NetworkOperation operation)
40 if (String.IsNullOrWhiteSpace(path))
41 throw new ArgumentNullException("path");
42 if (!Path.IsPathRooted(path))
43 throw new ArgumentException("path must be a rooted path", "path");
44 Contract.EndContractBlock();
46 var lower = path.ToLower();
47 NetworkState[lower] = operation;
48 //By default, None values don't need to be stored. They are stored anyway
49 //because TryRemove may fail.
50 if (operation == NetworkOperation.None)
52 NetworkOperation oldOperation;
53 NetworkState.TryRemove(lower, out oldOperation);
57 //Clients should acquire a NetworkGate before starting any network operation.
58 //If Acquire fails, another network operation is already in progress
59 public static NetworkGate Acquire(string path, NetworkOperation operation)
61 if (String.IsNullOrWhiteSpace(path))
62 throw new ArgumentNullException("path");
63 if (!Path.IsPathRooted(path))
64 throw new ArgumentException("path must be a rooted path", "path");
65 Contract.EndContractBlock();
67 var state = GetNetworkState(path);
68 //If no operation is in progress, return a NetworkGate
69 return (state == NetworkOperation.None)
70 ? new NetworkGate(path, operation)
71 //otherwise return a gate with Fail flagged
72 : new NetworkGate(path, NetworkOperation.None);
77 public string FilePath { get; private set; }
78 public NetworkOperation Operation { get; private set; }
80 private NetworkGate(string path,NetworkOperation operation)
82 if (String.IsNullOrWhiteSpace(path))
83 throw new ArgumentNullException("path");
84 Contract.EndContractBlock();
86 Operation = operation;
87 FilePath = path.ToLower();
89 //Skip dummy operations (those with Operation == None)
90 if (Operation != NetworkOperation.None)
91 //and store the file's operation
92 SetNetworkState(FilePath, operation);
95 //A NetworkGate has Failed if its operation is None
96 public bool Failed { get { return Operation == NetworkOperation.None; } }
98 //Release a gate by setting the NetworkOperation to None
103 //And reset the operation state for the file
104 SetNetworkState(FilePath,NetworkOperation.None);
108 public void Dispose()
111 GC.SuppressFinalize(this);
114 protected void Dispose(bool disposing)