public interface ISignal<T> : IDisposable { void Send(T signal); T Receive(); T Receive(int timeOut); }
[TestMethod] public void ExampleTest() { var signal = SignalFactory.GetInstanse<string>(); var task1 = Task.Factory.StartNew(() => // { Thread.Sleep(1000); signal.Send("Some message"); }); // string message = signal.Receive(); Debug.WriteLine(message); }
public static class SignalFactory { public static ISignal<T> GetInstanse<T>() { return new Signal<T>(); } public static ISignal<T> GetInstanse<T>(string name) { return new CrossProcessSignal<T>(name); } }
private T buffer; Dictionary<int,AutoResetEvent> events = new Dictionary<int, AutoResetEvent>(); private volatile object sync = new object(); private bool isDisposabled = false;
public void Dispose() { foreach(var resetEvent in events.Values) { resetEvent.Dispose(); } isDisposabled = true; } ~Signal() { if (!isDisposabled) { Dispose(); } }
public T Receive() { var waiter = GetEvents(); waiter.WaitOne(); waiter.Reset(); return buffer; }
public void Send(T signal) { lock (sync) { buffer = signal; foreach(var autoResetEvent in events.Values) { autoResetEvent.Set(); } } }
private void SendTest(string name = "") { ISignal<string> signal; if (string.IsNullOrEmpty(name)) { signal = SignalFactory.GetInstanse<string>(); // } else { signal = SignalFactory.GetInstanse<string>(name); } var task1 = Task.Factory.StartNew(() => // { for (int i = 0; i < 10; i++) { // , var message = signal.Receive(); Debug.WriteLine($"Thread 1 {message}"); } }); var task2 = Task.Factory.StartNew(() => // { for (int i = 0; i < 10; i++) { // , var message = signal.Receive(); Debug.WriteLine($"Thread 2 {message}"); } }); for (int i = 0; i < 10; i++) { // . signal.Send($"Ping {i}"); Thread.Sleep(50); } }
using System.Collections.Generic; using System.Threading; namespace Signal { internal class Signal<T> : ISignal<T> { private T buffer; Dictionary<int,AutoResetEvent> events = new Dictionary<int, AutoResetEvent>(); private volatile object sync = new object(); private bool isDisposabled = false; ~Signal() { if (!isDisposabled) { Dispose(); } } public T Receive() { var waiter = GetEvents(); waiter.WaitOne(); waiter.Reset(); return buffer; } public T Receive(int timeOut) { var waiter = GetEvents(); waiter.WaitOne(timeOut); waiter.Reset(); return buffer; } public void Send(T signal) { lock (sync) { buffer = signal; foreach(var autoResetEvent in events.Values) { autoResetEvent.Set(); } } } private AutoResetEvent GetEvents() { var threadId = Thread.CurrentThread.ManagedThreadId; AutoResetEvent autoResetEvent; if (!events.ContainsKey(threadId)) { autoResetEvent = new AutoResetEvent(false); events.Add(threadId, autoResetEvent); } else { autoResetEvent = events[threadId]; } return autoResetEvent; } public void Dispose() { foreach(var resetEvent in events.Values) { resetEvent.Dispose(); } isDisposabled = true; } } }
Source: https://habr.com/ru/post/336742/
All Articles