public static void BasicHttp_Streamed_Async_Delayed_Request_Throws_TimeoutException() { BasicHttpBinding binding = null; ChannelFactory<IWcfService> factory = null; IWcfService serviceProxy = null; Stream stream = null; int sendTimeoutMs = 3000; try { // *** SETUP *** \\ binding = new BasicHttpBinding(BasicHttpSecurityMode.None); binding.TransferMode = TransferMode.Streamed; binding.SendTimeout = TimeSpan.FromMilliseconds(sendTimeoutMs); factory = new ChannelFactory<IWcfService>(binding, new EndpointAddress(Endpoints.HttpBaseAddress_Basic)); serviceProxy = factory.CreateChannel(); // Create a read stream that deliberately times out during the async read during the request. // We also intercept the synchronous read because that path can also be executed during // an async read. stream = new TestMockStream() { CopyToAsyncFunc = (Stream destination, int bufferSize, CancellationToken ct) => { Task.Delay(sendTimeoutMs * 2).Wait(); return null; }, ReadFunc = (byte[] buffer, int offset, int count) => { Task.Delay(sendTimeoutMs * 2).Wait(); return -1; } }; // *** EXECUTE *** \\ Assert.Throws<TimeoutException>(() => { var unused = serviceProxy.EchoStreamAsync(stream).GetAwaiter().GetResult(); }); // *** VALIDATE *** \\ // *** CLEANUP *** \\ ((ICommunicationObject)serviceProxy).Close(); factory.Close(); } finally { // *** ENSURE CLEANUP *** \\ ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory); } }
public static void BasicHttp_Streamed_Async_Delayed_And_Aborted_Request_Throws_TimeoutException() { // This test is a regression test that verifies an issue discovered where exceeding the timeout // and aborting the channel before the client's Task completed led to incorrect error handling. BasicHttpBinding binding = null; ChannelFactory<IWcfService> factory = null; IWcfService serviceProxy = null; Stream stream = null; int sendTimeoutMs = 3000; try { // *** SETUP *** \\ binding = new BasicHttpBinding(BasicHttpSecurityMode.None); binding.TransferMode = TransferMode.Streamed; binding.SendTimeout = TimeSpan.FromMilliseconds(sendTimeoutMs); factory = new ChannelFactory<IWcfService>(binding, new EndpointAddress(Endpoints.HttpBaseAddress_Basic)); serviceProxy = factory.CreateChannel(); // Create a read stream that will both timeout and then abort the proxy channel when the // async read is called. We also intercept the synchronous read because that path can also // be executed during an async read. stream = new TestMockStream() { CopyToAsyncFunc = (Stream destination, int bufferSize, CancellationToken ct) => { // Abort to force the internal HttpClientChannelAsyncRequest.Cleanup() // to clear its data structures before the client's Task completes. Task.Delay(sendTimeoutMs * 2).Wait(); ((ICommunicationObject)serviceProxy).Abort(); return null; }, ReadFunc = (byte[] buffer, int offset, int count) => { // Abort to force the internal HttpClientChannelAsyncRequest.Cleanup() // to clear its data structures before the client's Task completes. Task.Delay(sendTimeoutMs * 2).Wait(); ((ICommunicationObject)serviceProxy).Abort(); return -1; } }; // *** EXECUTE *** \\ Assert.Throws<TimeoutException>(() => { var unused = serviceProxy.EchoStreamAsync(stream).GetAwaiter().GetResult(); }); // *** VALIDATE *** \\ // *** CLEANUP *** \\ ((ICommunicationObject)serviceProxy).Close(); factory.Close(); } finally { // *** ENSURE CLEANUP *** \\ ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory); } }