{"id":3776,"date":"2020-06-16T11:21:54","date_gmt":"2020-06-16T10:21:54","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=3776"},"modified":"2022-07-25T08:32:08","modified_gmt":"2022-07-25T07:32:08","slug":"c-signal-between-threads","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/c-signal-between-threads\/","title":{"rendered":"C# signal between threads"},"content":{"rendered":"\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nnamespace Domain.Helpers\n{\n    public class SignalWaiter : IDisposable\n    {\n        public delegate void SignalHandler();\n        private static readonly SynchronizedCollection&lt;KeyValuePair&lt;string, Semaphore>> Handlers = new SynchronizedCollection&lt;KeyValuePair&lt;string, Semaphore>>();\n\n        private readonly KeyValuePair&lt;string, Semaphore> _pair;\n        private readonly CancellationToken _cancellationToken;\n        private readonly TimeSpan _timeout;\n\n        public static void SendSignal(string key)\n        {\n            Handlers.Where(x => x.Key == key).Select(x => x.Value).ToList().ForEach(x => x.Release());\n        }\n\n        public SignalWaiter(string key) : this(key, TimeSpan.FromMinutes(1), new CancellationToken())\n        {\n        }\n        public SignalWaiter(string key, TimeSpan timeout, CancellationToken cancellationToken)\n        {\n            _pair = new KeyValuePair&lt;string, Semaphore>(key, new Semaphore(0, 1));\n            _cancellationToken = cancellationToken;\n            _timeout = timeout;\n            Handlers.Add(_pair);\n        }\n\n        public async Task Wait()\n        {\n            var task1 = Task.Run(() => _cancellationToken.WaitHandle.WaitOne());\n            var task2 = Task.Run(async () => await _pair.Value.WaitAsync(_timeout)); \/\/ _cancellationToken meegeven werkt niet afdoende\n            await Task.WhenAny(task1, task2);\n        }\n\n        #region IDisposable Support\n        private bool disposedValue = false;\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (!disposedValue)\n            {\n                if (disposing)\n                {\n                    Handlers.Remove(_pair);\n                    _pair.Value.Dispose();\n                }\n                disposedValue = true;\n            }\n        }\n        public void Dispose()\n        {\n            Dispose(true);\n        }\n        #endregion\n    }\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"><\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ example usage\nvar cancellationToken = Request.GetOwinContext()?.Request?.CallCancelled ?? default(CancellationToken);\nTask.Delay(15000).ContinueWith(x => SignalWaiter.SendSignal(\"signal1key\"));\nConsole.WriteLine($\"{DateTime.Now:o} starting\");\nusing (var signalWaiter = new SignalWaiter(\"signal1key\", TimeSpan.FromSeconds(60), cancellationToken))\n{\n        await signalWaiter.Wait();\n\tConsole.WriteLine($\"{DateTime.Now:o} signaled!\");\n}\nConsole.WriteLine($\"{DateTime.Now:o} finished!\");\nConsole.ReadKey();<\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[6,4,1],"tags":[],"class_list":["post-3776","post","type-post","status-publish","format-standard","hentry","category-dotnet","category-programming","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/3776","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=3776"}],"version-history":[{"count":6,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/3776\/revisions"}],"predecessor-version":[{"id":3786,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/3776\/revisions\/3786"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=3776"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=3776"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=3776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}