public void Worker_Threads_Stop_On_Dispose() { long count = 0; WorkerThreads threads = new WorkerThreads(TimeSpan.FromSeconds(5), (ts, obj) => { Interlocked.Increment(ref count); Thread.Sleep(100); }); try { int index = threads.AddWorker(); // pause a bit and make sure thread is working Thread.Sleep(1000); Assert.AreEqual(1, threads.Count); long curCount = Interlocked.Read(ref count); Assert.Greater(count, 0); threads.Dispose(); // pause a bit and make sure thread is actually dead long countAfterStop = Interlocked.Read(ref count); Thread.Sleep(1000); curCount = Interlocked.Read(ref count); Assert.AreEqual(curCount, countAfterStop); } finally { threads.Dispose(); } }
public void RemoveWorker_Aborts_Thread_After_Timeout() { long count = 0; using (WorkerThreads threads = new WorkerThreads(TimeSpan.FromSeconds(5), (ts, obj) => { Interlocked.Increment(ref count); Thread.Sleep(1000 * 30); Assert.Fail(); })) { int index = threads.AddWorker(); // pause a bit and make sure thread is working Thread.Sleep(1000); Assert.AreEqual(1, threads.Count); long curCount = Interlocked.Read(ref count); Assert.AreNotEqual(0, curCount); // has value been incremented threads.RemoveWorker(index); Assert.AreEqual(0, threads.Count); // pause a bit and make sure thread is actually dead long countAfterStop = Interlocked.Read(ref count); Thread.Sleep(1000); curCount = Interlocked.Read(ref count); Assert.AreEqual(curCount, countAfterStop); } }
/// <summary> /// Displays the window /// </summary> public PropertiesWindow() { WorkerThreads = Properties.Settings.Default.WorkerThreads; CompletionPortThreads = Properties.Settings.Default.CompletionPortThreads; SolvingAlgorithm = Properties.Settings.Default.SolvingAlgorithm; IPaddress = Properties.Settings.Default.IP; Port = Properties.Settings.Default.Port; InitializeComponent(); WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; workerSlot.DataContext = new TextboxText() { textdata = WorkerThreads.ToString() }; threadSlot.DataContext = new TextboxText() { textdata = CompletionPortThreads.ToString() }; solvingSlot.DataContext = new TextboxText() { textdata = SolvingAlgorithm }; ipAddressSlot.DataContext = new TextboxText() { textdata = SolvingAlgorithm }; portSlot.DataContext = new TextboxText() { textdata = SolvingAlgorithm }; }
/// <summary> /// Subscribes to Relative mouse movement /// </summary> /// <param name="mappingOptions">Options for the subscription (block, callback to fire etc)</param> /// <returns></returns> public void SubscribeMouseMoveRelative(MappingOptions mappingOptions) { _mouseMoveRelativeMapping = mappingOptions; if (!mappingOptions.Concurrent && !WorkerThreads.ContainsKey(8)) { WorkerThreads.TryAdd(8, new WorkerThread()); } _isFiltered = true; }
public static void Start(int workerThreads, bool compressFiles) { var realThreadNumber = workerThreads > 0 ? workerThreads : Environment.ProcessorCount; for (var i = 0; i < realThreadNumber; ++i) { WorkerThreads.Add(new FilePreprocessorThread(TaskQueue, $"FPP-0{i + 1}", compressFiles)); } WorkerThreads.ForEach(t => t.Start()); }
public void State_Is_Passed_To_Workers() { string state = "this is some state"; using (WorkerThreads threads = new WorkerThreads(TimeSpan.FromSeconds(5), (ts, obj) => { Assert.AreEqual(state, obj); })) { threads.AddWorker(state); Thread.Sleep(1000); } }
/// <summary> /// Unsubscribes from relative mouse movement /// </summary> public void UnsubscribeMouseMoveRelative() { if (_mouseMoveRelativeMapping == null) { return; } if (!_mouseMoveRelativeMapping.Concurrent && WorkerThreads.ContainsKey(8)) { WorkerThreads[8].Dispose(); WorkerThreads.TryRemove(8, out _); } _mouseMoveRelativeMapping = null; }
/// <summary> /// Unsubscribes from absolute mouse movement /// </summary> public void UnsubscribeMouseMoveAbsolute() { if (_mouseMoveAbsoluteMapping == null) { return; } if (!_mouseMoveAbsoluteMapping.Concurrent && WorkerThreads.ContainsKey(7)) { WorkerThreads[7].Dispose(); WorkerThreads.TryRemove(7, out _); } _mouseMoveAbsoluteMapping = null; }
public static bool FileInProgress(string fileName) { try { return(TaskQueue.Any(t => t.FileName == fileName) || WorkerThreads.Any(t => t.CurrentFile == fileName)); } catch (Exception ex) { LogException(LogLevel.Warning, ex); // Just in case return(true); } }
public void RemoveAll_Removes_All_Threads() { using (WorkerThreads threads = new WorkerThreads(TimeSpan.FromSeconds(5), (ts, obj) => { })) { for (int i = 0; i < 10; i++) { threads.AddWorker(); } Assert.AreEqual(10, threads.Count); threads.RemoveAll(); Assert.AreEqual(0, threads.Count); } }
protected override void OnStart() { base.OnStart(); _workers = new WorkerThreads(TimeSpan.FromSeconds(10), worker); _workers.AddWorkers(Environment.ProcessorCount); }
public static void Stop() => WorkerThreads.ForEach(t => t.Stop());
public override void ProcessStroke(List <ManagedWrapper.Stroke> strokes) { for (int i = 0; i < strokes.Count; i++) { var stroke = strokes[i]; var hasSubscription = false; var hasContext = ContextCallback != null; var moveRemoved = false; var hasMove = false; var x = stroke.mouse.x; var y = stroke.mouse.y; // Process mouse movement var isAbsolute = (stroke.mouse.flags & (ushort)ManagedWrapper.MouseFlag.MouseMoveAbsolute) == (ushort)ManagedWrapper.MouseFlag.MouseMoveAbsolute; //Determine whether or not to report mouse movement. // For Relative mode, this is fairly simple - if x and y are both 0, no movement was reported (Since a real mouse never reports x=0/y=0) // For Absolute mode, x=0/y=0 is reported, but we should limit this to only reporting once... // ... so when x=0/y=0 is seen in absolute mode, set the flag _absoluteMode00Reported to true and allow it to be reported... // then on subsequent reports of x=0/y=0 for absolute mode, if _absoluteMode00Reported is already true, then do not report movement... // ... In absolute mode, when x!=0/y!=0 is received, clear the _absoluteMode00Reported flag if (isAbsolute) { if (x == 0 && y == 0) { if (!_absoluteMode00Reported) { hasMove = true; _absoluteMode00Reported = true; } else { hasMove = false; } } else { hasMove = true; _absoluteMode00Reported = false; } } else { hasMove = (x != 0 || y != 0); } if (hasMove) { // Process Absolute Mouse Move if (isAbsolute) { if (_mouseMoveAbsoluteMapping != null) { var mapping = _mouseMoveAbsoluteMapping; hasSubscription = true; //var debugStr = $"AHK| Mouse stroke has absolute move of {x}, {y}..."; if (mapping.Concurrent) { ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(x, y)); } else if (WorkerThreads.ContainsKey(7)) { WorkerThreads[7]?.Actions.Add(() => mapping.Callback(x, y)); } if (mapping.Block) { moveRemoved = true; stroke.mouse.x = 0; stroke.mouse.y = 0; //debugStr += "Blocking"; } else { //debugStr += "Not Blocking"; } //Debug.WriteLine(debugStr); } } else { if (_mouseMoveRelativeMapping != null) { var mapping = _mouseMoveRelativeMapping; hasSubscription = true; //var debugStr = $"AHK| Mouse stroke has relative move of {x}, {y}..."; if (mapping.Concurrent) { ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(x, y)); } else if (WorkerThreads.ContainsKey(8)) { WorkerThreads[8]?.Actions.Add(() => mapping.Callback(x, y)); } if (mapping.Block) { moveRemoved = true; stroke.mouse.x = 0; stroke.mouse.y = 0; //debugStr += "Blocking"; } else { //debugStr += "Not Blocking"; } //Debug.WriteLine(debugStr); } } } var isMouseButtonsMapping = AllButtonsMapping != null; // Process Mouse Buttons - do this AFTER mouse movement, so that absolute mode has coordinates available at the point that the button callback is fired if (stroke.mouse.state != 0 && SingleButtonMappings.Count > 0 || isMouseButtonsMapping) { var btnStates = HelperFunctions.MouseStrokeToButtonStates(stroke); foreach (var btnState in btnStates) { if (!isMouseButtonsMapping && !SingleButtonMappings.ContainsKey(btnState.Button)) { continue; } hasSubscription = true; MappingOptions mapping = null; if (isMouseButtonsMapping) { mapping = AllButtonsMapping; } else { mapping = SingleButtonMappings[btnState.Button]; } var state = btnState; if (mapping.Concurrent) { if (isMouseButtonsMapping) { ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(btnState.Button, state.State)); } else { ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(state.State)); } } else { if (isMouseButtonsMapping) { DeviceWorkerThread?.Actions .Add(() => mapping.Callback(btnState.Button, state.State)); } else { WorkerThreads[btnState.Button]?.Actions .Add(() => mapping.Callback(state.State)); } } if (mapping.Block) { // Remove the event for this button from the stroke, leaving other button events intact stroke.mouse.state -= btnState.Flag; // If we are removing a mouse wheel event, then set rolling to 0 if no mouse wheel event left if (btnState.Flag == 0x400 || btnState.Flag == 0x800) { if ((stroke.mouse.state & 0x400) != 0x400 && (stroke.mouse.state & 0x800) != 0x800) { //Debug.WriteLine("AHK| Removing rolling flag from stroke"); stroke.mouse.rolling = 0; } } //Debug.WriteLine($"AHK| Removing flag {btnState.Flag} from stoke, leaving state {stroke.mouse.state}"); } else { //Debug.WriteLine($"AHK| Leaving flag {btnState.Flag} in stroke"); } } } // Forward on the stroke if required if (hasSubscription) { // Subscription mode // If the stroke has a move that was not removed, OR it has remaining button events, then forward on the stroke if ((hasMove && !moveRemoved) || stroke.mouse.state != 0) { //Debug.WriteLine($"AHK| Sending stroke. State = {stroke.mouse.state}. hasMove={hasMove}, moveRemoved={moveRemoved}"); ManagedWrapper.Send(DeviceContext, DeviceId, ref stroke, 1); } else { // Everything removed from stroke, do not forward //Debug.WriteLine("AHK| Mouse stroke now empty, not forwarding"); } } else if (hasContext) { // Context Mode - forward stroke with context wrapping ContextCallback(1); ManagedWrapper.Send(DeviceContext, DeviceId, ref stroke, 1); ContextCallback(0); } else { // No subscription or context mode - forward on //Debug.WriteLine($"AHK| Sending stroke. State = {stroke.mouse.state}. hasMove={hasMove}, moveRemoved={moveRemoved}"); ManagedWrapper.Send(DeviceContext, DeviceId, ref stroke, 1); } } }