/// <inheritdoc/> public T this[int index] { get { CheckIndex(index); try { ReaderWriterLock?.EnterReadLock(); return(MemUtil.GetRef <T>(GetPtr(index))); } finally { ReaderWriterLock?.ExitReadLock(); } } set { CheckIndex(index); try { ReaderWriterLock?.EnterWriteLock(); MemUtil.GetRef <T>(GetPtr(index)) = value; } finally { ReaderWriterLock?.ExitWriteLock(); } } }
/// <summary> /// Freezes updates if the collection was created as multithreaded. To resume updates dispose of the returned IDisposable. /// </summary> /// <returns></returns> public IDisposable FreezeUpdates() { _lock?.EnterReadLock(); return(new AnonDisposable(() => { _lock?.ExitReadLock(); })); }
public static void EnterExit() { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Assert.False(rwls.IsReadLockHeld); rwls.EnterReadLock(); Assert.True(rwls.IsReadLockHeld); rwls.ExitReadLock(); Assert.False(rwls.IsReadLockHeld); Assert.False(rwls.IsUpgradeableReadLockHeld); rwls.EnterUpgradeableReadLock(); Assert.True(rwls.IsUpgradeableReadLockHeld); rwls.ExitUpgradeableReadLock(); Assert.False(rwls.IsUpgradeableReadLockHeld); Assert.False(rwls.IsWriteLockHeld); rwls.EnterWriteLock(); Assert.True(rwls.IsWriteLockHeld); rwls.ExitWriteLock(); Assert.False(rwls.IsWriteLockHeld); Assert.False(rwls.IsUpgradeableReadLockHeld); rwls.EnterUpgradeableReadLock(); Assert.False(rwls.IsWriteLockHeld); Assert.True(rwls.IsUpgradeableReadLockHeld); rwls.EnterWriteLock(); Assert.True(rwls.IsWriteLockHeld); rwls.ExitWriteLock(); Assert.False(rwls.IsWriteLockHeld); Assert.True(rwls.IsUpgradeableReadLockHeld); rwls.ExitUpgradeableReadLock(); Assert.False(rwls.IsUpgradeableReadLockHeld); Assert.True(rwls.TryEnterReadLock(0)); rwls.ExitReadLock(); Assert.True(rwls.TryEnterReadLock(Timeout.InfiniteTimeSpan)); rwls.ExitReadLock(); Assert.True(rwls.TryEnterUpgradeableReadLock(0)); rwls.ExitUpgradeableReadLock(); Assert.True(rwls.TryEnterUpgradeableReadLock(Timeout.InfiniteTimeSpan)); rwls.ExitUpgradeableReadLock(); Assert.True(rwls.TryEnterWriteLock(0)); rwls.ExitWriteLock(); Assert.True(rwls.TryEnterWriteLock(Timeout.InfiniteTimeSpan)); rwls.ExitWriteLock(); } }
public static void ReaderWriterLockSlimPerf() { ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { rwLock.EnterReadLock(); rwLock.ExitReadLock(); } } }
public static void Dispose() { ReaderWriterLockSlim rwls; rwls = new ReaderWriterLockSlim(); rwls.Dispose(); Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterReadLock(0)); Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterUpgradeableReadLock(0)); Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterWriteLock(0)); rwls.Dispose(); for (int i = 0; i < 3; i++) { rwls = new ReaderWriterLockSlim(); switch (i) { case 0: rwls.EnterReadLock(); break; case 1: rwls.EnterUpgradeableReadLock(); break; case 2: rwls.EnterWriteLock(); break; } Assert.Throws<SynchronizationLockException>(() => rwls.Dispose()); } }
private bool ForkAndExecProcess( string filename, string[] argv, string[] envp, string cwd, bool redirectStdin, bool redirectStdout, bool redirectStderr, bool setCredentials, uint userId, uint groupId, uint[] groups, out int stdinFd, out int stdoutFd, out int stderrFd, bool usesTerminal, bool throwOnNoExec = true) { if (string.IsNullOrEmpty(filename)) { throw new Win32Exception(Interop.Error.ENOENT.Info().RawErrno); } // Lock to avoid races with OnSigChild // By using a ReaderWriterLock we allow multiple processes to start concurrently. s_processStartLock.EnterReadLock(); try { if (usesTerminal) { ConfigureTerminalForChildProcesses(1); } int childPid; // Invoke the shim fork/execve routine. It will create pipes for all requested // redirects, fork a child process, map the pipe ends onto the appropriate stdin/stdout/stderr // descriptors, and execve to execute the requested process. The shim implementation // is used to fork/execve as executing managed code in a forked process is not safe (only // the calling thread will transfer, thread IDs aren't stable across the fork, etc.) int errno = Interop.Sys.ForkAndExecProcess( filename, argv, envp, cwd, redirectStdin, redirectStdout, redirectStderr, setCredentials, userId, groupId, groups, out childPid, out stdinFd, out stdoutFd, out stderrFd); if (errno == 0) { // Ensure we'll reap this process. // note: SetProcessId will set this if we don't set it first. _waitStateHolder = new ProcessWaitState.Holder(childPid, isNewChild: true, usesTerminal); // Store the child's information into this Process object. Debug.Assert(childPid >= 0); SetProcessId(childPid); SetProcessHandle(new SafeProcessHandle(_processId, GetSafeWaitHandle())); return(true); } else { if (!throwOnNoExec && new Interop.ErrorInfo(errno).Error == Interop.Error.ENOEXEC) { return(false); } throw new Win32Exception(errno); } } finally { s_processStartLock.ExitReadLock(); if (_waitStateHolder == null && usesTerminal) { // We failed to launch a child that could use the terminal. s_processStartLock.EnterWriteLock(); ConfigureTerminalForChildProcesses(-1); s_processStartLock.ExitWriteLock(); } } }
/// <summary> /// Creates an HTTP request for the given URI. /// </summary> /// <param name="requestUri">The request URI.</param> /// <returns>An HTTP request.</returns> public IHttpRequest <HttpContent> CreateHttpRequest(Uri requestUri) { HttpClient httpClient; if (_clientConfig.CacheHttpClient) { // If a HttpClient has already been created for the service client then just reuse it. if (_cachedHttpClient != null) { httpClient = _cachedHttpClient; } else if (!CanClientConfigBeSerialized(_clientConfig)) { lock (_httpClientCacheCreateLock) { // Check if the HttpClient was created by some other thread // while this thread was waiting for the lock. if (_cachedHttpClient != null) { httpClient = _cachedHttpClient; } else { httpClient = CreateHttpClient(_clientConfig); _cachedHttpClient = httpClient; } } } else { // Check to see if an HttpClient was created by another service client with the // same settings on the ClientConfig. var configUniqueString = CreateConfigUniqueString(_clientConfig); bool found; _httpClientCacheRWLock.EnterReadLock(); try { found = _httpClientCache.TryGetValue(configUniqueString, out httpClient); } finally { _httpClientCacheRWLock.ExitReadLock(); } if (found) { _cachedHttpClient = httpClient; } else { _httpClientCacheRWLock.EnterWriteLock(); try { found = _httpClientCache.TryGetValue(configUniqueString, out httpClient); if (found) { _cachedHttpClient = httpClient; } else { lock (_httpClientCacheCreateLock) { // Check if the HttpClient was created by some other thread // while this thread was waiting for the lock. if (_cachedHttpClient != null) { httpClient = _cachedHttpClient; } else { httpClient = CreateHttpClient(_clientConfig); _cachedHttpClient = httpClient; _httpClientCache[configUniqueString] = httpClient; } } } } finally { _httpClientCacheRWLock.ExitWriteLock(); } } } } else { httpClient = CreateHttpClient(_clientConfig); } return(new HttpWebRequestMessage(httpClient, requestUri, _clientConfig)); }
private async Task HandleUpload(HttpConnection p, string path) { bool responseListPage = p.ParseUrlQstr()["infoonly"] != "1"; string info = null; if (!(allow_create | allow_edit)) { info = $"{strMissingPermission("create")} and {strMissingPermission("edit")}."; goto FAIL; } var reader = new MultipartFormDataReader(p); int count = 0; string saveFileName = null; string encoding = "utf-8"; while (await reader.ReadNextPartHeader()) { if (reader.CurrentPartName == "file") { var fileName = reader.CurrentPartFileName; if (!CheckPathForWriting(path, fileName, out info, out var realPath)) { goto FAIL; } if (!TryOpenFile(path, fileName + ".uploading", out var fs, out info, out var tempPath)) { goto FAIL; } try { using (fs) { await NaiveUtils.StreamCopyAsync(reader, fs); } MoveOrReplace(tempPath, realPath); } catch (Exception e) { Logger.exception(e, Logging.Level.Warning, $"receiving file '{fileName}' from {p.myStream}."); File.Delete(realPath); if (e is DisconnectedException) { return; } info = $"IO error on '{saveFileName}'"; goto FAIL; } Logger.info($"uploaded '{fileName}' by {p.myStream}."); count++; } else if (reader.CurrentPartName.Is("textFileName").Or("fileName")) { saveFileName = await reader.ReadAllTextAsync(); } else if (reader.CurrentPartName == "textFileEncoding") { encoding = await reader.ReadAllTextAsync(); } else if (reader.CurrentPartName == "textContent") { if (!CheckPathForWriting(path, saveFileName, out info, out var realPath)) { goto FAIL; } if (!TryOpenFile(path, saveFileName + ".uploading", out var fs, out info, out var tempPath)) { goto FAIL; } try { using (fs) { if (encoding == "utf-8") { await NaiveUtils.StreamCopyAsync(reader, fs, bs : 8 * 1024); } else { using (var sr = new StreamReader(reader)) { using (var sw = new StreamWriter(fs, Encoding.GetEncoding(encoding))) { const int bufLen = 8 * 1024; var buf = new char[bufLen]; var read = await sr.ReadAsync(buf, 0, bufLen); await sw.WriteAsync(buf, 0, read); } } } } MoveOrReplace(tempPath, realPath); } catch (Exception e) { Logger.exception(e, Logging.Level.Warning, $"receiving text file '{saveFileName}' from {p.myStream}."); File.Delete(tempPath); if (e is DisconnectedException) { return; } info = $"IO error on '{saveFileName}'"; goto FAIL; } Logger.info($"uploaded text '{saveFileName}' by {p.myStream}."); count++; } else if (reader.CurrentPartName == "mkdir") { var dirName = await reader.ReadAllTextAsync(); if (!CheckPathForWriting(path, dirName, out info, out var realPath)) { goto FAIL; } try { Directory.CreateDirectory(realPath); } catch (Exception) { info = $"Failed to create directory '{dirName}'"; goto FAIL; } Logger.info($"created dir '{dirName}' by {p.myStream}."); count++; } else if (reader.CurrentPartName == "rm") { var delFile = await reader.ReadAllTextAsync(); if (!CheckPathForWriting(path, delFile, out info, out var realPath, out var r)) { goto FAIL; } try { if (r == WebSvrHelper.PathResult.Directory) { Directory.Delete(realPath); } else if (r == WebSvrHelper.PathResult.File) { File.Delete(realPath); } else { info = $"Failed to delete '{delFile}' (not found)."; goto FAIL; } } catch (Exception) { info = $"Failed to delete '{delFile}'"; goto FAIL; } Logger.info($"deleted '{delFile}' by {p.myStream}."); count++; } else if (reader.CurrentPartName == "netdl") { if (!allow_netdl) { info = $"{strMissingPermission("netdl")}."; goto FAIL; } var unparsed = await reader.ReadAllTextAsync(); var args = Naive.Console.Command.SplitArguments(unparsed); string url, name; if (args.Length == 0 || args.Length > 2) { info = $"wrong arguments."; goto FAIL; } url = args[0]; if (args.Length == 2) { name = args[1]; } else { int startIndex = url.LastIndexOf('/'); if (startIndex < 0) { info = "can not determine a filename from the given url, please specify one."; goto FAIL; } name = url.Substring(startIndex); } if (!CheckPathForWriting(path, name, out info, out var realPath, out var r)) { goto FAIL; } if (r == WebSvrHelper.PathResult.Directory) { name = Path.Combine(url.Substring(url.LastIndexOf('/')), name); if (!CheckPathForWriting(path, name, out info, out realPath)) { goto FAIL; } } if (!CheckPathForWriting(path, name + ".downloading", out info, out var realDlPath)) { goto FAIL; } var dlTask = new DownloadTask(url, realDlPath); // double checked locking, add the new task into the dict if no task already exist. downloadTasksLock.EnterReadLock(); var taskExists = downloadTasks.TryGetValue(realDlPath, out var oldTask); downloadTasksLock.ExitReadLock(); if (!taskExists) { downloadTasksLock.EnterWriteLock(); taskExists = downloadTasks.TryGetValue(realDlPath, out oldTask); if (!taskExists) { downloadTasks.Add(realDlPath, dlTask); } downloadTasksLock.ExitWriteLock(); } if (taskExists) { if (oldTask.State <= DownloadTask.States.running) { info = "a task is already running on this path."; goto FAIL; } else { info = $"override a '{oldTask.State}' task.\n"; downloadTasksLock.EnterWriteLock(); downloadTasks[realDlPath] = dlTask; downloadTasksLock.ExitWriteLock(); } } try { var t = NaiveUtils.RunAsyncTask(async() => { try { await dlTask.Start(); MoveOrReplace(realDlPath, realPath); } finally { // Whether success or not, remove the task from list after 5 minutes. AsyncHelper.SetTimeout(5 * 60 * 1000, () => { downloadTasksLock.EnterWriteLock(); downloadTasks.Remove(realDlPath); downloadTasksLock.ExitWriteLock(); }); } }); if (await t.WithTimeout(200)) { info += "downloading task is started."; } else { await t; info += "downloaded."; } } catch (Exception e) { Logger.exception(e, Logging.Level.Warning, $"downloading from '{url}' to '{realDlPath}'"); info += "downloading failed."; goto FAIL; } count++; } else if (reader.CurrentPartName.Is("mv").Or("cp")) { var unparsed = await reader.ReadAllTextAsync(); var args = Naive.Console.Command.SplitArguments(unparsed); if (args.Length < 2) { info = $"too few arguments"; goto FAIL; } string to = args[args.Length - 1]; if (!CheckPathForWriting(path, to, out info, out var toPath, out var toType)) { goto FAIL; } bool multipleFrom = args.Length > 2; if (multipleFrom && toType != WebSvrHelper.PathResult.Directory) { info = "multiple 'from' when 'to' is not a directory!"; goto FAIL; } for (int i = 0; i < args.Length - 1; i++) { string from = args[i]; if (!CheckPathForWriting(path, from, out info, out var fromPath)) { goto FAIL; } string toFilePath = toType == WebSvrHelper.PathResult.Directory ? Path.Combine(toPath, Path.GetFileName(from)) : toPath; // TODO: refine directory moving/copying try { if (reader.CurrentPartName == "mv") { MoveOrReplace(fromPath, toFilePath); } else { File.Copy(fromPath, toFilePath, true); } } catch (Exception e) { Logger.exception(e, Logging.Level.Warning, $"file mv/cp from '{fromPath}' to '{toFilePath}' by {p.myStream}."); info = "error occurred during file operation at " + from; goto FAIL; } count++; } } else if (reader.CurrentPartName == "rmm") { var unparsed = await reader.ReadAllTextAsync(); var args = Naive.Console.Command.SplitArguments(unparsed); if (args.Length == 0) { info = "no arguments."; goto FAIL; } foreach (var delFile in args) { if (!CheckPathForWriting(path, delFile, out info, out var realPath, out var r)) { goto FAIL; } try { if (r == WebSvrHelper.PathResult.Directory) { Directory.Delete(realPath); } else if (r == WebSvrHelper.PathResult.File) { File.Delete(realPath); } else { info = $"Failed to delete '{delFile}' (not found)"; goto FAIL; } } catch (Exception) { info = $"Failed to delete '{delFile}'"; goto FAIL; } Logger.info($"deleted '{delFile}' by {p.myStream}."); count++; } } else if (reader.CurrentPartName.Is("infoonly").Or("isajax")) { responseListPage = false; } else { info = $"Unknown part name '{reader.CurrentPartName}'"; goto FAIL; } } if (info == null || count > 1) { info = $"Finished {count} operation{(count > 1 ? "s" : null)}."; } FAIL: if (responseListPage) { await HandleDirList(p, path, info); } else { p.Handled = true; p.setContentTypeTextPlain(); await p.writeLineAsync(info); } }
public static void InvalidExits(LockRecursionPolicy policy) { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(policy)) { Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); rwls.EnterReadLock(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock()); rwls.ExitWriteLock(); using (Barrier barrier = new Barrier(2)) { Task t = Task.Factory.StartNew(() => { rwls.EnterWriteLock(); barrier.SignalAndWait(); barrier.SignalAndWait(); rwls.ExitWriteLock(); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); barrier.SignalAndWait(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); barrier.SignalAndWait(); t.GetAwaiter().GetResult(); } } }
public static void WriterToReaderChain() { using (AutoResetEvent are = new AutoResetEvent(false)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { rwls.EnterWriteLock(); Task t = Task.Factory.StartNew(() => { Assert.False(rwls.TryEnterReadLock(TimeSpan.FromMilliseconds(10))); Task.Run(() => are.Set()); // ideally this won't fire until we've called EnterReadLock, but it's a benign race in that the test will succeed either way rwls.EnterReadLock(); rwls.ExitReadLock(); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); are.WaitOne(); rwls.ExitWriteLock(); t.GetAwaiter().GetResult(); } }
/// <summary> /// This will save any player in the OfflinePlayers dictionary that has ChangesDetected. The biotas are saved in parallel. /// </summary> public static void SaveOfflinePlayersWithChanges() { lastDatabaseSave = DateTime.UtcNow; var biotas = new Collection <(Biota biota, ReaderWriterLockSlim rwLock)>(); playersLock.EnterReadLock(); try { foreach (var player in offlinePlayers.Values) { if (player.ChangesDetected) { player.SaveBiotaToDatabase(false); biotas.Add((player.Biota, player.BiotaDatabaseLock)); } } } finally { playersLock.ExitReadLock(); } DatabaseManager.Shard.SaveBiotasInParallel(biotas, result => { }); }
public IndexData Append(Stream input) { if (input == null) { throw new ArgumentNullException(nameof(input)); } CheckDisposed(); var length = input.Length; var cursor = Interlocked.Add(ref _cursor, length) - length; EnsureCapacity(cursor, length); var indexData = new IndexData { Offset = cursor, Size = length }; var buffer = new byte[_readBufferSize]; var count = input.Read(buffer, 0, _readBufferSize); var prevCount = count; var prevBuffer = Interlocked.Exchange(ref buffer, new byte[_readBufferSize]); using (var hashAlgorithm = MD5.Create()) { do { _lock.EnterReadLock(); try { if (prevCount > 0) { using (var writer = _file.CreateViewStream(cursor, prevCount, MemoryMappedFileAccess.Write)) { writer.Write(prevBuffer, 0, prevCount); cursor += prevCount; } } } finally { _lock.ExitReadLock(); } count = input.Read(buffer, 0, _readBufferSize); if (count > 0) { hashAlgorithm.TransformBlock(prevBuffer, 0, prevCount, null, 0); prevCount = count; prevBuffer = Interlocked.Exchange(ref buffer, prevBuffer); } else { hashAlgorithm.TransformFinalBlock(prevBuffer, 0, prevCount); break; } } while (true); indexData.Md5Hash = hashAlgorithm.Hash; } return(indexData); }
public void Batch(Action <IStorageActionsAccessor> action) { if (disposerLock.IsReadLockHeld && disableBatchNesting.Value == null) // we are currently in a nested Batch call and allow to nest batches { var storageActionsAccessor = current.Value; if (storageActionsAccessor != null) // check again, just to be sure { storageActionsAccessor.IsNested = true; action(storageActionsAccessor); storageActionsAccessor.IsNested = false; return; } } Action afterStorageCommit; disposerLock.EnterReadLock(); try { if (disposed) { Trace.WriteLine("TransactionalStorage.Batch was called after it was disposed, call was ignored.\r\n" + new StackTrace(true)); return; // this may happen if someone is calling us from the finalizer thread, so we can't even throw on that } afterStorageCommit = ExecuteBatch(action); } catch (Exception e) { if (disposed) { Trace.WriteLine("TransactionalStorage.Batch was called after it was disposed, call was ignored.\r\n" + e); if (System.Environment.StackTrace.Contains(".Finalize()") == false) { throw; } return; // this may happen if someone is calling us from the finalizer thread, so we can't even throw on that } if (e.InnerException is VoronExceptions.ConcurrencyException) { throw new ConcurrencyException("Concurrent modification to the same document are not allowed", e.InnerException); } if (e.InnerException is VoronExceptions.VoronUnrecoverableErrorException) { Trace.WriteLine("Voron has encountered unrecoverable error. The database will be disabled.\r\n" + e.InnerException); onStorageInaccessible(); throw e.InnerException; } throw; } finally { disposerLock.ExitReadLock(); if (disposed == false && disableBatchNesting.Value == null) { current.Value = null; } } if (afterStorageCommit != null) { afterStorageCommit(); } if (onCommit != null) { onCommit(); // call user code after we exit the lock } }
// // This routine is a wrapper around a hashtable containing mappings // of privilege names to LUIDs // private static Luid LuidFromPrivilege(string privilege) { Luid luid; luid.LowPart = 0; luid.HighPart = 0; // // Look up the privilege LUID inside the cache // try { privilegeLock.EnterReadLock(); if (luids.ContainsKey(privilege)) { luid = luids[privilege]; privilegeLock.ExitReadLock(); } else { privilegeLock.ExitReadLock(); if (false == Interop.Advapi32.LookupPrivilegeValue(null, privilege, out luid)) { int error = Marshal.GetLastWin32Error(); if (error == Interop.Errors.ERROR_NOT_ENOUGH_MEMORY) { throw new OutOfMemoryException(); } else if (error == Interop.Errors.ERROR_ACCESS_DENIED) { throw new UnauthorizedAccessException(); } else if (error == Interop.Errors.ERROR_NO_SUCH_PRIVILEGE) { throw new ArgumentException( SR.Format(SR.Argument_InvalidPrivilegeName, privilege)); } else { System.Diagnostics.Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "LookupPrivilegeValue() failed with unrecognized error code {0}", error)); throw new InvalidOperationException(); } } privilegeLock.EnterWriteLock(); } } finally { if (privilegeLock.IsReadLockHeld) { privilegeLock.ExitReadLock(); } if (privilegeLock.IsWriteLockHeld) { if (!luids.ContainsKey(privilege)) { luids[privilege] = luid; privileges[luid] = privilege; } privilegeLock.ExitWriteLock(); } } return(luid); }
// TODO: Consider how to make the log not clear every startup and still have it be feasible for people to "post their log" internal static void Log(string message, Exception?ex = null, bool stackTrace = false, bool methodName = true, [CallerMemberName] string callerMemberName = "") { try { Lock.EnterReadLock(); if (File.Exists(Paths.LogFile) && new FileInfo(Paths.LogFile).Length > ByteSize.MB * 50) { ClearLogFile(); } } catch (Exception ex1) { Debug.WriteLine(ex1); } finally { try { Lock.ExitReadLock(); } catch (Exception logEx) { Debug.WriteLine(logEx); } } try { Lock.EnterWriteLock(); using var sw = new StreamWriter(Paths.LogFile, append: true); string methodNameStr = methodName ? callerMemberName + "\r\n" : ""; sw.WriteLine(GetDateTimeStringFast() + " " + methodNameStr + message); if (stackTrace) { sw.WriteLine("STACK TRACE:\r\n" + new StackTrace(1)); } if (ex != null) { sw.WriteLine("EXCEPTION:\r\n" + ex); } sw.WriteLine(); } catch (Exception logEx) { Debug.WriteLine(logEx); } finally { try { Lock.ExitWriteLock(); } catch (Exception logEx) { Debug.WriteLine(logEx); } } }
public ReaderLock Enter() { _lock.EnterReadLock(); return(this); }
private void ProcessMessage() { int receiveSize = Transport.ReceiveFrom(_buffer, 0, _buffer.Length, -1, out IPEndPoint senderEndpoint); if (receiveSize != _buffer.Length) { return; } if (_buffer[0] != (byte)MessageType.Register) { return; } // Address IPAddress senderAddress = senderEndpoint.Address; // Register client packet byte registerFlags = _buffer[1]; bool isConnector = (registerFlags & 1) == 1; bool isListener = ((registerFlags >> 1) & 1) == 1; if (isListener) { _listenerClientsLock.EnterUpgradeableReadLock(); try { if (_listenerClients.TryGetValue(senderAddress, out Client client)) { _listenerClientsLock.EnterWriteLock(); try { client.EndPoint = senderEndpoint; client.IsConnector = isConnector; client.IsListener = isListener; client.LastRegisterTime = DateTime.Now; } finally { _listenerClientsLock.ExitWriteLock(); } } else { _listenerClientsLock.EnterWriteLock(); try { _listenerClients.Add(senderAddress, new Client() { EndPoint = senderEndpoint, IsConnector = isConnector, IsListener = isListener, LastRegisterTime = DateTime.Now }); } finally { _listenerClientsLock.ExitWriteLock(); } } } finally { _listenerClientsLock.ExitUpgradeableReadLock(); } // Prevent info leaks Array.Clear(_buffer, 0, _buffer.Length); // Write message type _buffer[0] = (byte)MessageType.Registered; // Send to listener Transport.SendTo(_buffer, 0, _buffer.Length, -1, senderEndpoint); } if (isConnector) { // Copy address to address buffer Buffer.BlockCopy(_buffer, 2, _ipBuffer, 0, 4); // Parse address IPAddress listenerAddress = new IPAddress(_ipBuffer); // Read token size byte tokenSize = _buffer[6]; // Validate token size if (tokenSize > _buffer.Length - 6) { // Invalid token size return; } // Copy token to token buffer Buffer.BlockCopy(_buffer, 7, _tokenBuffer, 0, tokenSize); _listenerClientsLock.EnterReadLock(); try { // Look for the client they wish to connec tto if (_listenerClients.TryGetValue(listenerAddress, out Client listenerClient) && listenerClient.IsListener) { // Write message type _buffer[0] = (byte)MessageType.ConnectTo; // Write address Buffer.BlockCopy(listenerClient.EndPoint.Address.GetAddressBytes(), 0, _buffer, 1, 4); // Write port _buffer[5] = (byte)listenerClient.EndPoint.Port; _buffer[6] = (byte)(listenerClient.EndPoint.Port >> 8); // Write token length _buffer[7] = tokenSize; // Write token Buffer.BlockCopy(_tokenBuffer, 0, _buffer, 8, tokenSize); // Send to connector Transport.SendTo(_buffer, 0, _buffer.Length, -1, senderEndpoint); // Write address Buffer.BlockCopy(senderAddress.GetAddressBytes(), 0, _buffer, 1, 4); // Write port _buffer[5] = (byte)senderEndpoint.Port; _buffer[6] = (byte)(senderEndpoint.Port >> 8); // Send to listener Transport.SendTo(_buffer, 0, _buffer.Length, -1, listenerClient.EndPoint); } else { // Prevent info leaks Array.Clear(_buffer, 0, _buffer.Length); _buffer[0] = (byte)MessageType.Error; _buffer[1] = (byte)ErrorType.ClientNotFound; // Send error Transport.SendTo(_buffer, 0, _buffer.Length, -1, senderEndpoint); } } finally { _listenerClientsLock.ExitReadLock(); } } }
internal static Disposer WithReadLock(this ReaderWriterLockSlim rwls) { rwls.EnterReadLock(); return(new Disposer(() => rwls.ExitReadLock())); }
public IDisposable LockRead() { return(new ActionDisposable(() => @lock.EnterReadLock(), () => @lock.ExitReadLock())); }
/// <summary> /// 读取文件内容 /// </summary> /// <param name="folderPath">文件夹路径</param> /// <param name="fileName">文件名</param> /// <param name="encode">编码</param> /// <param name="readType">读取类型(0:精准,1:前缀模糊)</param> /// <returns></returns> public static string ReadLog(string folderPath, string fileName, Encoding encode, ReadType readType = ReadType.Accurate) { string s = ""; try { LogWriteLock.EnterReadLock(); // 根据文件名读取当前文件内容 if (readType == ReadType.Accurate) { var filePath = Path.Combine(folderPath, fileName); if (!File.Exists(filePath)) { s = null; } else { StreamReader f2 = new StreamReader(filePath, encode); s = f2.ReadToEnd(); f2.Close(); f2.Dispose(); } } // 根据前缀读取所有文件内容 if (readType == ReadType.Prefix) { var allFiles = new DirectoryInfo(folderPath); var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower())).ToList(); foreach (var item in selectFiles) { if (File.Exists(item.FullName)) { StreamReader f2 = new StreamReader(item.FullName, encode); s += f2.ReadToEnd(); f2.Close(); f2.Dispose(); } } } // 根据前缀读取 最新文件 时间倒叙 if (readType == ReadType.PrefixLatest) { var allFiles = new DirectoryInfo(folderPath); var selectLastestFile = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower())).OrderByDescending(d => d.Name).FirstOrDefault(); if (selectLastestFile != null && File.Exists(selectLastestFile.FullName)) { StreamReader f2 = new StreamReader(selectLastestFile.FullName, encode); s = f2.ReadToEnd(); f2.Close(); f2.Dispose(); } } } catch (Exception) { FailedCount++; } finally { LogWriteLock.ExitReadLock(); } return(s); }
public ReadLockToken(ReaderWriterLockSlim readLock) { this._lock = readLock; readLock.EnterReadLock(); }
Node GetNode() { if (Interlocked.Increment(ref _totalHitCounter) % 50 == 0) { // try to sort... var upgraded = false; _nodeLock.EnterUpgradeableReadLock(); try { var curNode = _positions.First; while (curNode != null) { var chkNode = curNode; while (chkNode.Previous != null && chkNode.Previous.Value.HitCount < curNode.Value.HitCount) { chkNode = chkNode.Previous; } if (chkNode != curNode) { var temp = curNode.Next; if (!upgraded) { _nodeLock.EnterWriteLock(); upgraded = true; } _positions.Remove(curNode); _positions.AddBefore(chkNode, curNode); curNode = temp; } else { curNode = curNode.Next; } } } finally { if (upgraded) { _nodeLock.ExitWriteLock(); } _nodeLock.ExitUpgradeableReadLock(); } } LinkedListNode <Node> node; var thread = Thread.CurrentThread; _nodeLock.EnterReadLock(); try { node = _positions.First; while (node != null) { if (node.Value.Thread == thread) { // found it! ++node.Value.HitCount; return(node.Value); } node = node.Next; } } finally { _nodeLock.ExitReadLock(); } // not found, create a new node and add it node = new LinkedListNode <Node>( new Node { Thread = thread, Position = 0L, HitCount = 1, } ); _nodeLock.EnterWriteLock(); try { _positions.AddLast(node); } finally { _nodeLock.ExitWriteLock(); } return(node.Value); }
public IDisposable ExecutingWork() { readerWriterLockSlim.EnterReadLock(); return(new DisposableAction(readerWriterLockSlim.ExitReadLock)); }
public IDisposable CurrentlyIndexing() { currentlyIndexingLock.EnterReadLock(); return(new DisposableAction(currentlyIndexingLock.ExitReadLock)); }
protected void EnterReadLock() => _lock?.EnterReadLock();
public static void DeadlockAvoidance() { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock()); rwls.ExitReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); rwls.EnterWriteLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.ExitWriteLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.ExitWriteLock(); } using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion)) { rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); rwls.ExitReadLock(); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); rwls.EnterReadLock(); rwls.EnterUpgradeableReadLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterReadLock(); rwls.ExitReadLock(); rwls.ExitReadLock(); rwls.EnterWriteLock(); rwls.EnterWriteLock(); rwls.ExitWriteLock(); rwls.ExitWriteLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); rwls.EnterReadLock(); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); rwls.ExitWriteLock(); rwls.ExitWriteLock(); } }
/// <inheritdoc /> public IDisposable AcquireReaderLock() { _locker?.EnterReadLock(); return(new SyncLockReleaser(this, LockHolderType.Read)); }
public static void ReadersMayBeConcurrent() { using (Barrier barrier = new Barrier(2)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Assert.Equal(0, rwls.CurrentReadCount); Task.WaitAll( Task.Run(() => { rwls.EnterReadLock(); barrier.SignalAndWait(); // 1 Assert.True(rwls.IsReadLockHeld); barrier.SignalAndWait(); // 2 Assert.Equal(2, rwls.CurrentReadCount); barrier.SignalAndWait(); // 3 barrier.SignalAndWait(); // 4 rwls.ExitReadLock(); }), Task.Run(() => { barrier.SignalAndWait(); // 1 rwls.EnterReadLock(); barrier.SignalAndWait(); // 2 Assert.True(rwls.IsReadLockHeld); Assert.Equal(0, rwls.WaitingReadCount); barrier.SignalAndWait(); // 3 rwls.ExitReadLock(); barrier.SignalAndWait(); // 4 })); Assert.Equal(0, rwls.CurrentReadCount); } }
/// <summary> /// Processes a SPARQL Query sending the results to a RDF/SPARQL Results handler as appropriate /// </summary> /// <param name="rdfHandler">RDF Handler</param> /// <param name="resultsHandler">Results Handler</param> /// <param name="query">SPARQL Query</param> public void ProcessQuery(IRdfHandler rdfHandler, ISparqlResultsHandler resultsHandler, SparqlQuery query) { //Do Handler null checks before evaluating the query if (query == null) { throw new ArgumentNullException("query", "Cannot evaluate a null query"); } if (rdfHandler == null && (query.QueryType == SparqlQueryType.Construct || query.QueryType == SparqlQueryType.Describe || query.QueryType == SparqlQueryType.DescribeAll)) { throw new ArgumentNullException("rdfHandler", "Cannot use a null RDF Handler when the Query is a CONSTRUCT/DESCRIBE"); } if (resultsHandler == null && (query.QueryType == SparqlQueryType.Ask || SparqlSpecsHelper.IsSelectQuery(query.QueryType))) { throw new ArgumentNullException("resultsHandler", "Cannot use a null resultsHandler when the Query is an ASK/SELECT"); } //Handle the Thread Safety of the Query Evaluation #if !NO_RWLOCK ReaderWriterLockSlim currLock = (this._dataset is IThreadSafeDataset) ? ((IThreadSafeDataset)this._dataset).Lock : this._lock; try { currLock.EnterReadLock(); #endif //Reset Query Timers query.QueryExecutionTime = null; bool datasetOk = false, defGraphOk = false; try { //Set up the Default and Active Graphs if (query.DefaultGraphs.Any()) { //Call HasGraph() on each Default Graph but ignore the results, we just do this //in case a dataset has any kind of load on demand behaviour foreach (Uri defGraphUri in query.DefaultGraphs) { this._dataset.HasGraph(defGraphUri); } this._dataset.SetDefaultGraph(query.DefaultGraphs); defGraphOk = true; } else if (query.NamedGraphs.Any()) { //No FROM Clauses but one/more FROM NAMED means the Default Graph is the empty graph this._dataset.SetDefaultGraph(Enumerable.Empty <Uri>()); } this._dataset.SetActiveGraph(this._dataset.DefaultGraphUris); datasetOk = true; //Convert to Algebra and execute the Query SparqlEvaluationContext context = this.GetContext(query); BaseMultiset result; try { context.StartExecution(); ISparqlAlgebra algebra = query.ToAlgebra(); result = context.Evaluate(algebra); context.EndExecution(); query.QueryExecutionTime = new TimeSpan(context.QueryTimeTicks); } catch (RdfQueryException) { context.EndExecution(); query.QueryExecutionTime = new TimeSpan(context.QueryTimeTicks); throw; } catch { context.EndExecution(); query.QueryExecutionTime = new TimeSpan(context.QueryTimeTicks); throw; } //Return the Results switch (query.QueryType) { case SparqlQueryType.Ask: case SparqlQueryType.Select: case SparqlQueryType.SelectAll: case SparqlQueryType.SelectAllDistinct: case SparqlQueryType.SelectAllReduced: case SparqlQueryType.SelectDistinct: case SparqlQueryType.SelectReduced: //For SELECT and ASK can populate a Result Set directly from the Evaluation Context //return new SparqlResultSet(context); resultsHandler.Apply(context); break; case SparqlQueryType.Construct: //Create a new Empty Graph for the Results try { rdfHandler.StartRdf(); foreach (String prefix in query.NamespaceMap.Prefixes) { if (!rdfHandler.HandleNamespace(prefix, query.NamespaceMap.GetNamespaceUri(prefix))) { ParserHelper.Stop(); } } //Construct the Triples for each Solution foreach (ISet s in context.OutputMultiset.Sets) { //List<Triple> constructedTriples = new List<Triple>(); try { ConstructContext constructContext = new ConstructContext(rdfHandler, s, false); foreach (IConstructTriplePattern p in query.ConstructTemplate.TriplePatterns.OfType <IConstructTriplePattern>()) { try { if (!rdfHandler.HandleTriple(p.Construct(constructContext))) { ParserHelper.Stop(); } //constructedTriples.Add(((IConstructTriplePattern)p).Construct(constructContext)); } catch (RdfQueryException) { //If we get an error here then we could not construct a specific triple //so we continue anyway } } } catch (RdfQueryException) { //If we get an error here this means we couldn't construct for this solution so the //entire solution is discarded continue; } //h.Assert(constructedTriples); } rdfHandler.EndRdf(true); } catch (RdfParsingTerminatedException) { rdfHandler.EndRdf(true); } catch { rdfHandler.EndRdf(false); throw; } break; case SparqlQueryType.Describe: case SparqlQueryType.DescribeAll: //For DESCRIBE we retrieve the Describe algorithm and apply it ISparqlDescribe describer = query.Describer; describer.Describe(rdfHandler, context); break; default: throw new RdfQueryException("Unknown query types cannot be processed by Leviathan"); } } finally { if (defGraphOk) { this._dataset.ResetDefaultGraph(); } if (datasetOk) { this._dataset.ResetActiveGraph(); } } #if !NO_RWLOCK } finally { currLock.ExitReadLock(); } #endif }
public static void ReleaseReadersWhenWaitingWriterTimesOut() { using (var rwls = new ReaderWriterLockSlim()) { // Enter the read lock rwls.EnterReadLock(); // Typical order of execution: 0 Thread writeWaiterThread; using (var beforeTryEnterWriteLock = new ManualResetEvent(false)) { writeWaiterThread = new Thread(() => { // Typical order of execution: 1 // Add a writer to the wait list for enough time to allow successive readers to enter the wait list while this // writer is waiting beforeTryEnterWriteLock.Set(); if (rwls.TryEnterWriteLock(2000)) { // The typical order of execution is not guaranteed, as sleep times are not guaranteed. For // instance, before this write lock is added to the wait list, the two new read locks may be // acquired. In that case, the test may complete before or while the write lock is taken. rwls.ExitWriteLock(); } // Typical order of execution: 4 }); writeWaiterThread.IsBackground = true; writeWaiterThread.Start(); beforeTryEnterWriteLock.WaitOne(); } Thread.Sleep(1000); // wait for TryEnterWriteLock to enter the wait list // A writer should now be waiting, add readers to the wait list. Since a read lock is still acquired, the writer // should time out waiting, then these readers should enter and exit the lock. ThreadStart EnterAndExitReadLock = () => { // Typical order of execution: 2, 3 rwls.EnterReadLock(); // Typical order of execution: 5, 6 rwls.ExitReadLock(); }; var readerThreads = new Thread[] { new Thread(EnterAndExitReadLock), new Thread(EnterAndExitReadLock) }; foreach (var readerThread in readerThreads) { readerThread.IsBackground = true; readerThread.Start(); } foreach (var readerThread in readerThreads) { readerThread.Join(); } rwls.ExitReadLock(); // Typical order of execution: 7 writeWaiterThread.Join(); } }
protected void ReadLock() { _lock.EnterReadLock(); }
public static IDisposable UseReadLock(this ReaderWriterLockSlim locker) { locker?.EnterReadLock(); return(new DisposeActionWrapper(() => locker?.ExitReadLock())); }
public override int GetOrdinal(FacetLabel cp) { EnsureOpen(); if (cp.Length == 0) { return(ROOT_ORDINAL); } // First try to find the answer in the LRU cache: // LUCENENET: Despite LRUHashMap being thread-safe, we get much better performance // if reads are separated from writes. ordinalCacheLock.EnterReadLock(); try { if (ordinalCache.TryGetValue(cp, out Int32Class res)) { if (res < indexReader.MaxDoc) { // Since the cache is shared with DTR instances allocated from // doOpenIfChanged, we need to ensure that the ordinal is one that // this DTR instance recognizes. return(res); } else { // if we get here, it means that the category was found in the cache, // but is not recognized by this TR instance. Therefore there's no // need to continue search for the path on disk, because we won't find // it there too. return(TaxonomyReader.INVALID_ORDINAL); } } } finally { ordinalCacheLock.ExitReadLock(); } // If we're still here, we have a cache miss. We need to fetch the // value from disk, and then also put it in the cache: int ret = TaxonomyReader.INVALID_ORDINAL; DocsEnum docs = MultiFields.GetTermDocsEnum(indexReader, null, Consts.FULL, new BytesRef(FacetsConfig.PathToString(cp.Components, cp.Length)), 0); if (docs != null && docs.NextDoc() != DocIdSetIterator.NO_MORE_DOCS) { ret = docs.DocID; // we only store the fact that a category exists, not its inexistence. // This is required because the caches are shared with new DTR instances // that are allocated from doOpenIfChanged. Therefore, if we only store // information about found categories, we cannot accidently tell a new // generation of DTR that a category does not exist. ordinalCacheLock.EnterWriteLock(); try { ordinalCache[cp] = ret; } finally { ordinalCacheLock.ExitWriteLock(); } } return(ret); }
public void Dispose() { _readerWriterLock?.EnterReadLock(); _readerWriterLock = null; }
public PhysicsObj GetKnownObject(uint objectGuid) { rwLock.EnterReadLock(); try { KnownObjects.TryGetValue(objectGuid, out var obj); return(obj); } finally { rwLock.ExitReadLock(); } }
internal static void AddEventHandler <T>(Func <T, EventRegistrationToken> addMethod, Action <EventRegistrationToken> removeMethod, T handler) { // The instanceKey will be IUnknown * of the target object object instanceKey = GetInstanceKey(removeMethod); // Call addMethod outside of RW lock // At this point we don't need to worry about race conditions and we can avoid deadlocks // if addMethod waits on finalizer thread // If we later throw we need to remove the method EventRegistrationToken token = addMethod(handler); bool tokenAdded = false; try { EventRegistrationTokenListWithCount tokens; // // The whole add/remove code has to be protected by a reader/writer lock // Add/Remove cannot run at the same time with cache cleanup but Add/Remove can run at the same time // s_eventCacheRWLock.EnterReadLock(); try { // Add the method, and make a note of the delegate -> token mapping. EventCacheEntry registrationTokens = GetOrCreateEventRegistrationTokenTable(instanceKey, removeMethod); try { registrationTokens.LockAcquire(); // // We need to find the key that equals to this handler // Suppose we have 3 handlers A, B, C that are equal (refer to the same object and method), // the first handler (let's say A) will be used as the key and holds all the tokens. // We don't need to hold onto B and C, because the COM object itself will keep them alive, // and they won't die anyway unless the COM object dies or they get unsubscribed. // It may appear that it is fine to hold A, B, C, and add them and their corresponding tokens // into registrationTokens table. However, this is very dangerous, because this COM object // may die, but A, B, C might not get collected yet, and another COM object comes into life // with the same IUnknown address, and we subscribe event B. In this case, the right token // will be added into B's token list, but once we unsubscribe B, we might end up removing // the last token in C, and that may lead to crash. // object key = FindEquivalentKeyUnsafe(registrationTokens.registrationTable, handler, out tokens); if (key == null) { tokens = new EventRegistrationTokenListWithCount(registrationTokens.tokenListCount, token); registrationTokens.registrationTable.Add(handler, tokens); } else { tokens.Push(token); } tokenAdded = true; } finally { registrationTokens.LockRelease(); } } finally { s_eventCacheRWLock.ExitReadLock(); } #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event subscribed for instance = " + instanceKey + ", handler = " + handler + "\n"); #endif } catch (Exception) { // If we've already added the token and go there, we don't need to "UNDO" anything if (!tokenAdded) { // Otherwise, "Undo" addMethod if any exception occurs // There is no need to cleanup our data structure as we haven't added the token yet removeMethod(token); } throw; } }
public void Connect(string host = "localhost", int port = 10111) { Console.WriteLine("Connecting to: {0}:{1}", host, port); try { client.Connect(host, port); client.NoDelay = true; Running = true; this.NetworkStream = client.GetStream(); readerTokenSource = new CancellationTokenSource(); CancellationToken tk1 = readerTokenSource.Token; Task.Run(() => { while (!readerTokenSource.IsCancellationRequested) { try { var commandString = ReadCommand(); //System.Diagnostics.Debug.WriteLine("Reply from Server: {0}", commandString); var response = Serializer.DeserializeJson <APIResponse>(commandString); if (commandString.Length > 0) { CommandReceived(this, new CommandReceivedEventArgs(response, commandString)); } } catch (Exception ex) { //Console.WriteLine("Error! Lost connection to Infinite Flight! \n" + ex.ToString() + "\nError! Lost connection to Infinite Flight!"); Console.WriteLine("Error! Lost connection to Infinite Flight!"); disconnect(); } } }); writerTokenSource = new CancellationTokenSource(); CancellationToken tk2 = writerTokenSource.Token; Task.Run(() => { while (!writerTokenSource.IsCancellationRequested) { apiCallQueueLock.EnterReadLock(); var pendingItems = apiCallQueue.Any(); apiCallQueueLock.ExitReadLock(); if (pendingItems) { try { apiCallQueueLock.EnterWriteLock(); var apiCall = apiCallQueue.Dequeue(); apiCallQueueLock.ExitWriteLock(); if (apiCall != null) { WriteObject(apiCall); } } catch (Exception ex) { Console.WriteLine("Error sending command to Infinite Flight! \n" + ex.ToString() + "\nError sending command to Infinite Flight!"); disconnect(); } } else { Thread.Sleep(60); } } }); } catch (System.Net.Sockets.SocketException e) { Console.WriteLine("Caught exception: {0}", e); } }