public async void Start(MockChannel channel, CancellationTokenSource cancel) { await Task.Yield(); signal = new ManualResetEventSlim(false); while (!cancel.IsCancellationRequested && disposed == 0) { signal.Wait(cancel.Token); while (queue.TryDequeue(out var request) && !cancel.IsCancellationRequested && disposed == 0) { await channel.Buffer.Fill(request.data, (int)request.data.Length, cancel.Token).ConfigureAwait(false); } } signal.Dispose(); }
private static async Task test(bool hostInstance, params object[] arguments) { var proxyGenerator = new DefaultProxyFactory(); using (var cancel = new CancellationTokenSource(Debugger.IsAttached ? TimeSpan.FromDays(1) : TimeSpan.FromMinutes(1))) using (var localChannel = new MockChannel()) using (var remoteChannel = new MockChannel()) { var writeTask = new TaskCompletionSource <(long id, Stream data)>(); cancel.Token.Register(() => writeTask.TrySetCanceled()); localChannel.MockConnection.Writes += (id, data) => writeTask.TrySetResult((id, data)); remoteChannel.MockConnection.Writes += (id, data) => writeTask.TrySetResult((id, data)); //make a local start on another thread var localStart = localChannel.LocalStart(cancel, proxyGenerator, typeof(DummyClass).GetConstructors() .FirstOrDefault(ctor => ctor.GetParameters().Length == arguments.Length) ?? typeof(DummyClass).GetConstructors() .First(ctor => ctor.GetParameters().Length != arguments.Length), hostInstance, arguments); if (localStart.IsCompleted) { //this usually means an error happened so lets throw it now await localStart.ConfigureAwait(false); } //wait for local start to start the waiting step for a response await writeTask.Task.ConfigureAwait(false); //read the write request from the local channel var writeRequest = writeTask.Task.Result; Assert.AreEqual(localChannel.Id, writeRequest.id); Assert.IsNotNull(writeRequest.data); writeTask = new TaskCompletionSource <(long id, Stream data)>(); //send the request to the remote channel await remoteChannel.Buffer.Fill(writeRequest.data, (int)writeRequest.data.Length, cancel.Token).ConfigureAwait(false); var remoteStart = await remoteChannel.RemoteStart(cancel, proxyGenerator).ConfigureAwait(false); await writeTask.Task.ConfigureAwait(false); //read the write request from the remote channel writeRequest = writeTask.Task.Result; Assert.AreEqual(remoteChannel.Id, writeRequest.id); Assert.IsNotNull(writeRequest.data); //send the request to the local channel await localChannel.Buffer.Fill(writeRequest.data, (int)writeRequest.data.Length, cancel.Token).ConfigureAwait(false); //wait for all start tasks to finish await localStart.ConfigureAwait(false); //validate local instance var localInstance = localStart.Result as DummyClass; Assert.IsNotNull(localInstance); Assert.AreEqual(localInstance.Arg1, arguments.Skip(0).FirstOrDefault()); Assert.AreEqual(localInstance.Arg2, arguments.Skip(1).FirstOrDefault()); Assert.AreEqual(localInstance.Arg3, arguments.Skip(2).FirstOrDefault()); //validate remote instance var remoteInstance = remoteStart.instance as DummyClass; Assert.IsNotNull(remoteInstance); Assert.AreEqual(remoteInstance.Arg1, arguments.Skip(0).FirstOrDefault()); Assert.AreEqual(remoteInstance.Arg2, arguments.Skip(1).FirstOrDefault()); Assert.AreEqual(remoteInstance.Arg3, arguments.Skip(2).FirstOrDefault()); //validate proxy was generated correctly if (hostInstance) { Assert.IsFalse(remoteStart.isHost); Assert.AreEqual(typeof(DummyClass), localInstance.GetType()); Assert.AreNotEqual(typeof(DummyClass), remoteInstance.GetType()); } else { Assert.IsTrue(remoteStart.isHost); Assert.AreNotEqual(typeof(DummyClass), localInstance.GetType()); Assert.AreEqual(typeof(DummyClass), remoteInstance.GetType()); } } }