Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Implementation]: Use TimeSpan everywhere we use an int for seconds, milliseconds, and timeouts (Group 1/3) #64860

Merged
merged 75 commits into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
377d39c
Add GC (CoreCLR) `TimeSpan` overloads
deeprobin Feb 5, 2022
4d5b632
Add `CancellationToken` overload for `Wait`
deeprobin Feb 5, 2022
3477de9
Add `MatchTimeout` property to `RegularExpressionAttribute`
deeprobin Feb 5, 2022
ca4e786
Add tests for `RegularExpressionAttribute.MatchTimeout`
deeprobin Feb 5, 2022
98664c6
Add `TimeSpan` overloads for `WaitForInputIdle` and `WaitForExit`
deeprobin Feb 5, 2022
94412fd
Add `TimeSpan` overload for `Timer` constructor
deeprobin Feb 5, 2022
31b2210
Add `TimeSpan` overload for `ServiceBase.RequestAdditionalTime`
deeprobin Feb 5, 2022
a3d856b
Add `TimeSpan` overload for `NetworkStream.Close`
deeprobin Feb 5, 2022
77e959b
Add `TimeSpan` overloads for `Socket.Poll` and `Socket.Select`
deeprobin Feb 5, 2022
ea86b67
Add `TimeSpan` overload for `FileSystemWatcher.WaitForChanged`
deeprobin Feb 5, 2022
517b8e7
Add `TimeSpan` overloads for `NamedPipeClientStram.Connect` and `Name…
deeprobin Feb 5, 2022
47cb9f8
Add `TimeSpan` overloads for `Ping.Send` and `Ping.SendPingAsync`
deeprobin Feb 5, 2022
829d412
Add more tests for `Ping.Send` and `Ping.SendPingAsync`
deeprobin Feb 5, 2022
f413126
Add tests for `NamedPipeClientStream.Connect` and `NamedPipeClientStr…
deeprobin Feb 5, 2022
516041c
Add more `Task.Wait` tests
deeprobin Feb 5, 2022
74fb1d9
Add ref
deeprobin Feb 5, 2022
7deaa98
Refactor RunContinuationCancelTest_TimeSpan test
deeprobin Feb 10, 2022
6827e20
Remove redundant code duplication
deeprobin Feb 10, 2022
615b66e
Remove extra line
deeprobin Feb 10, 2022
6413304
Use meaningful timeSpan
deeprobin Feb 10, 2022
004914c
Use Timeout.InfiniteTimeSpan
deeprobin Feb 10, 2022
091c289
Inline method call
deeprobin Feb 10, 2022
70c4efa
Use checked `Close`
deeprobin Feb 10, 2022
eeeb61b
Use expression body style in System.Net.Ping
deeprobin Feb 10, 2022
7446821
Implement CancellationTokenHandling to `SendPingAsync`
deeprobin Feb 10, 2022
5fba0ab
Fix PingTest
deeprobin Feb 10, 2022
738b9e2
Use expression-body method style for `GC`
deeprobin Feb 10, 2022
e6d68f9
Use expression-body method style for `Process`
deeprobin Feb 10, 2022
4a35788
Use expression-body method style for `FileSystemWatcher`
deeprobin Feb 10, 2022
486a761
Use expression-body method style for `NamedPipeStream`
deeprobin Feb 10, 2022
0a0794f
Merge branch 'issue-14336' of https://github.com/deeprobin/runtime in…
deeprobin Feb 10, 2022
9ffe1ae
Fix `NamedPipeTest.Specific`
deeprobin Feb 10, 2022
7d4af1d
Use expression-body method style for `NetworkStream` and `Socket`
deeprobin Feb 10, 2022
27fa0ce
Fix syntax errors in `PingTest`
deeprobin Feb 10, 2022
abea06f
Add `GC` implementation for NativeAOT (CoreRT)
deeprobin Feb 10, 2022
340e5eb
Add Mono `GC` implementation
deeprobin Feb 11, 2022
0ff42de
Next try to fix `RemoteExecutor` tests
deeprobin Feb 11, 2022
e61acf0
Fix `RemoteExecutor` tests
deeprobin Feb 11, 2022
5279de8
Fix net48 tests
deeprobin Feb 11, 2022
aad5405
Move ref into only-core ref & add cond. compilation
deeprobin Feb 11, 2022
1529601
Move `Timer`-`TimeSpan` overload in the right assembly
deeprobin Feb 14, 2022
c3ea515
Update `Task.Wait` so that it verifies the `CancellationToken` before…
deeprobin Feb 14, 2022
53bed23
Use `ToTimeoutMilliseconds` instead of a checked cast to int
deeprobin Feb 14, 2022
80f10be
Remove redundant TimerConstructor test
deeprobin Feb 15, 2022
6805ad4
Add setter to `RegularExpressionAttribute.MatchTimeout`
deeprobin Feb 15, 2022
f5e4844
Use `ToTimeoutMilliseconds` in `WaitForInputIdle`
deeprobin Feb 15, 2022
cf68f4d
Merge branch 'main' into issue-14336
deeprobin Feb 21, 2022
ff9c0e6
Use legacy syntax instead of pattern matching
deeprobin Mar 10, 2022
3be4f23
Merge branch 'main' into issue-14336
deeprobin Mar 18, 2022
099aacb
Remove setter from `RegularExpressionAttribute.MatchTimeout`
deeprobin Mar 18, 2022
d659806
Centralize `GC` methods
deeprobin Mar 18, 2022
eef5d71
Apply suggestions
deeprobin Mar 18, 2022
b9aca93
Add doc comment to `Process.WaitForInputIdle`
deeprobin Mar 18, 2022
ca7edd2
Reduce test duplication to reduce opportunities to flake out
deeprobin Mar 18, 2022
3a47e9d
Reduce test duplication for NamedPipes
deeprobin Mar 18, 2022
a469722
Reduce PingTests
deeprobin Mar 18, 2022
6251c56
Re-order `System.Net.Sockets` ref assembly entry
deeprobin Mar 18, 2022
a888f6e
Fix time unit conversion in `NetworkStream` & `Socket`
deeprobin Mar 18, 2022
c6a6c05
Use new overload in `Task.Wait(TimeSpan)`
deeprobin Mar 18, 2022
cfba2b9
Remove redundant test
deeprobin Mar 18, 2022
75b8554
Fix ping tests
deeprobin Mar 18, 2022
03aa02d
Fix Pipe tests
deeprobin Mar 18, 2022
25484a4
Use simpler validation and remove redundant resx-resources
deeprobin Mar 19, 2022
4c06f93
Remove unintentional changes
deeprobin Mar 19, 2022
ea03c06
Use `timeout.Ticks / 10` instead of floating-point multiplication
deeprobin Mar 25, 2022
4d2e023
Style fix
deeprobin Mar 25, 2022
bba4bd3
Improve naming: `timeoutMillis` -> `timeoutMilliseconds`
deeprobin Mar 25, 2022
c774885
Add tests
deeprobin Mar 25, 2022
2f47067
Fix file ending
deeprobin Mar 25, 2022
0d0015f
Fix sol file
deeprobin Mar 25, 2022
77f921f
Inline `ToTimeoutMilliseconds`
deeprobin Mar 26, 2022
a97f7d3
Fix coding style
deeprobin Mar 26, 2022
7cdf76c
Improve test maintainability of `System.Net.Sockets`
deeprobin Mar 26, 2022
4a73007
Apply suggestions
deeprobin Mar 26, 2022
f56905d
Update src/libraries/System.ServiceProcess.ServiceController/tests/Se…
danmoseley Mar 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
<Compile Include="$(BclSourcesRoot)\System\Enum.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Environment.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Exception.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\GC.cs" />
<Compile Include="$(BclSourcesRoot)\System\GC.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\FileLoadException.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\FileNotFoundException.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Math.CoreCLR.cs" />
Expand Down Expand Up @@ -333,9 +333,9 @@

<Target Name="GenerateEventingFiles"
Inputs="@(EventingGenerationScript);@(EventManifestFile)"
Outputs="@(EventingSourceFile)"
DependsOnTargets="FindPython"
BeforeTargets="BeforeCompile">
Outputs="@(EventingSourceFile)"
DependsOnTargets="FindPython"
BeforeTargets="BeforeCompile">

<Error Condition="'$(PYTHON)' == ''" Text="Unable to locate Python. NativeRuntimeEventSource.CoreCLR.cs cannot be generated without Python installed on the machine. Either install Python in your path or point to it with the PYTHON environment variable." />
<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
<Compile Include="System\Diagnostics\StackTrace.CoreRT.cs" />
<Compile Include="System\Enum.CoreRT.cs" />
<Compile Include="System\Environment.CoreRT.cs" />
<Compile Include="System\GC.cs" />
<Compile Include="System\GC.CoreRT.cs" />
<Compile Include="System\Helpers.cs" />
<Compile Include="System\Math.CoreRT.cs" />
<Compile Include="System\MathF.CoreRT.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ internal enum EndNoGCRegionStatus
AllocationExceeded = 3
}

public static class GC
public static partial class GC
{
public static int GetGeneration(object obj)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ public partial class RegularExpressionAttribute : System.ComponentModel.DataAnno
{
public RegularExpressionAttribute([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute(System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.Regex)] string pattern) { }
public int MatchTimeoutInMilliseconds { get { throw null; } set { } }
public System.TimeSpan MatchTimeout { get { throw null; } }
public string Pattern { get { throw null; } }
public override string FormatErrorMessage(string name) { throw null; }
public override bool IsValid(object? value) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public RegularExpressionAttribute([StringSyntax(StringSyntaxAttribute.Regex)] st
/// </summary>
public int MatchTimeoutInMilliseconds { get; set; }

/// <summary>
/// Gets the timeout to use when matching the regular expression pattern
/// </summary>
public TimeSpan MatchTimeout => TimeSpan.FromMilliseconds(MatchTimeoutInMilliseconds);

/// <summary>
/// Gets the regular expression pattern to use
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<Compile Include="System\ComponentModel\DataAnnotations\PhoneAttributeTests.cs" />
<Compile Include="System\ComponentModel\DataAnnotations\RangeAttributeTests.cs" Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'" />
<Compile Include="System\ComponentModel\DataAnnotations\RegularExpressionAttributeTests.cs" />
<Compile Include="System\ComponentModel\DataAnnotations\RegularExpressionAttributeTests.Core.cs" Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'" />
<Compile Include="System\ComponentModel\DataAnnotations\RequiredAttributeTests.cs" />
<Compile Include="System\ComponentModel\DataAnnotations\ScaffoldColumnAttributeTests.cs" />
<Compile Include="System\ComponentModel\DataAnnotations\Schema\ColumnAttributeTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.ComponentModel.DataAnnotations;
using Xunit;

namespace System.ComponentModel.Annotations.Tests.System.ComponentModel.DataAnnotations
{
public sealed partial class RegularExpressionAttributeTests
{
[Theory]
[InlineData(12345)]
[InlineData(-1)]
public static void MatchTimeout_Get_ReturnsExpected(int newValue)
{
var attribute = new RegularExpressionAttribute("SomePattern") { MatchTimeoutInMilliseconds = newValue };
Assert.Equal(TimeSpan.FromMilliseconds(newValue), attribute.MatchTimeout);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace System.ComponentModel.DataAnnotations.Tests
{
public class RegularExpressionAttributeTests : ValidationAttributeTestBase
public sealed partial class RegularExpressionAttributeTests : ValidationAttributeTestBase
{
protected override IEnumerable<TestCase> ValidValues()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2338,6 +2338,7 @@ public partial class Timer : System.ComponentModel.Component, System.ComponentMo
{
public Timer() { }
public Timer(double interval) { }
public Timer(System.TimeSpan interval) { }
[System.ComponentModel.DefaultValueAttribute(true)]
public bool AutoReset { get { throw null; } set { } }
[System.ComponentModel.DefaultValueAttribute(false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ public Timer(double interval) : this()
_interval = (int)roundedInterval;
}

/// <summary>
/// Initializes a new instance of the <see cref='Timer'/> class, setting the <see cref='Interval'/> property to the specified period.
/// </summary>
public Timer(TimeSpan interval) : this(interval.TotalMilliseconds)
{
}

/// <summary>
/// Gets or sets a value indicating whether the Timer raises the Tick event each time the specified
/// Interval has elapsed, when Enabled is set to true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,11 @@ public void Refresh() { }
public override string ToString() { throw null; }
public void WaitForExit() { }
public bool WaitForExit(int milliseconds) { throw null; }
public bool WaitForExit(System.TimeSpan timeout) { throw null; }
public System.Threading.Tasks.Task WaitForExitAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public bool WaitForInputIdle() { throw null; }
public bool WaitForInputIdle(int milliseconds) { throw null; }
public bool WaitForInputIdle(System.TimeSpan timeout) { throw null; }
}
[System.ComponentModel.DesignerAttribute("System.Diagnostics.Design.ProcessModuleDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public partial class ProcessModule : System.ComponentModel.Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,39 @@ public bool WaitForInputIdle(int milliseconds)
return WaitForInputIdleCore(milliseconds);
}

/// <summary>
/// Causes the <see cref="Process"/> component to wait the specified <paramref name="timeout"/> for the associated process to enter an idle state.
/// This overload applies only to processes with a user interface and, therefore, a message loop.
/// </summary>
/// <param name="timeout">The amount of time, in milliseconds, to wait for the associated process to become idle.</param>
/// <returns><see langword="true"/> if the associated process has reached an idle state; otherwise, <see langword="false"/>.</returns>
/// <exception cref="InvalidOperationException">
/// The process does not have a graphical interface.
///
/// -or-
///
/// An unknown error occurred. The process failed to enter an idle state.
///
/// -or-
///
/// The process has already exited.
///
/// -or-
///
/// No process is associated with this <see cref="Process"/> object.
/// </exception>
/// <remarks>
/// Use <see cref="WaitForInputIdle(TimeSpan)"/> to force the processing of your application
/// to wait until the message loop has returned to the idle state.
/// When a process with a user interface is executing, its message loop executes every time
/// a Windows message is sent to the process by the operating system.
/// The process then returns to the message loop. A process is said to be in an idle state
/// when it is waiting for messages inside of a message loop.
/// This state is useful, for example, when your application needs to wait for a starting process
/// to finish creating its main window before the application communicates with that window.
/// </remarks>
public bool WaitForInputIdle(TimeSpan timeout) => WaitForInputIdle(ToTimeoutMilliseconds(timeout));

public ISynchronizeInvoke? SynchronizingObject { get; set; }

/// <devdoc>
Expand Down Expand Up @@ -1414,6 +1447,22 @@ public bool WaitForExit(int milliseconds)
return exited;
}

/// <summary>
/// Instructs the Process component to wait the specified number of milliseconds for
/// the associated process to exit.
/// </summary>
public bool WaitForExit(TimeSpan timeout) => WaitForExit(ToTimeoutMilliseconds(timeout));

private static int ToTimeoutMilliseconds(TimeSpan timeout)
{
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(timeout));
}
return (int)totalMilliseconds;
}

/// <summary>
/// Instructs the Process component to wait for the associated process to exit, or
/// for the <paramref name="cancellationToken"/> to be canceled.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ private void AssertNonZeroAllZeroDarwin(long value)
}
}

[Theory]
[InlineData(-2)]
[InlineData((long)int.MaxValue + 1)]
public void TestWaitForExitValidation(long milliseconds)
{
CreateDefaultProcess();
Assert.Throws<ArgumentOutOfRangeException>("timeout", () => _process.WaitForExit(TimeSpan.FromMilliseconds(milliseconds)));
}

[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[PlatformSpecific(TestPlatforms.Windows)] // Expected behavior varies on Windows and Unix
public void TestBasePriorityOnWindows()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ protected void OnError(System.IO.ErrorEventArgs e) { }
protected void OnRenamed(System.IO.RenamedEventArgs e) { }
public System.IO.WaitForChangedResult WaitForChanged(System.IO.WatcherChangeTypes changeType) { throw null; }
public System.IO.WaitForChangedResult WaitForChanged(System.IO.WatcherChangeTypes changeType, int timeout) { throw null; }
public System.IO.WaitForChangedResult WaitForChanged(System.IO.WatcherChangeTypes changeType, System.TimeSpan timeout) { throw null; }
}
public partial class InternalBufferOverflowException : System.SystemException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,19 @@ public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, int ti
WaitForChangedResult.TimedOutResult;
}

public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, TimeSpan timeout) =>
WaitForChanged(changeType, ToTimeoutMilliseconds(timeout));

private static int ToTimeoutMilliseconds(TimeSpan timeout)
{
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(timeout));
}
return (int)totalMilliseconds;
}

/// <devdoc>
/// Stops and starts this object.
/// </devdoc>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,50 +76,73 @@ public static void WaitForChangedResult_TimedOut_Roundtrip()
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void ZeroTimeout_TimesOut(bool enabledBeforeWait)
[InlineData(-2)]
[InlineData((long)int.MaxValue + 1)]
public void TimeSpan_ArgumentValidation(long milliseconds)
{
TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds);
using var testDirectory = new TempDirectory(GetTestFilePath());
using var _ = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName()));
using var fsw = new FileSystemWatcher(testDirectory.Path);

Assert.Throws<ArgumentOutOfRangeException>("timeout", () => fsw.WaitForChanged(WatcherChangeTypes.All, timeout));
}

[Theory]
[InlineData(false, true)]
[InlineData(true, false)]
public void ZeroTimeout_TimesOut(bool enabledBeforeWait, bool useTimeSpan)
{
using (var testDirectory = new TempDirectory(GetTestFilePath()))
using (var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())))
using (var fsw = new FileSystemWatcher(testDirectory.Path))
{
if (enabledBeforeWait) fsw.EnableRaisingEvents = true;
AssertTimedOut(fsw.WaitForChanged(WatcherChangeTypes.All, 0));

const int timeoutMilliseconds = 0;
AssertTimedOut(useTimeSpan
? fsw.WaitForChanged(WatcherChangeTypes.All, TimeSpan.FromMilliseconds(timeoutMilliseconds))
: fsw.WaitForChanged(WatcherChangeTypes.All, timeoutMilliseconds));
Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents);
}
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void NonZeroTimeout_NoEvents_TimesOut(bool enabledBeforeWait)
[InlineData(false, false)]
[InlineData(true, true)]
public void NonZeroTimeout_NoEvents_TimesOut(bool enabledBeforeWait, bool useTimeSpan)
{
using (var testDirectory = new TempDirectory(GetTestFilePath()))
using (var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())))
using (var fsw = new FileSystemWatcher(testDirectory.Path))
{
if (enabledBeforeWait) fsw.EnableRaisingEvents = true;
AssertTimedOut(fsw.WaitForChanged(0, 1));
const int timeoutMilliseconds = 1;
AssertTimedOut(useTimeSpan
? fsw.WaitForChanged(0, TimeSpan.FromMilliseconds(timeoutMilliseconds))
: fsw.WaitForChanged(0, timeoutMilliseconds));
Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents);
}
}

[Theory]
[InlineData(WatcherChangeTypes.Deleted, false)]
[InlineData(WatcherChangeTypes.Created, true)]
[InlineData(WatcherChangeTypes.Changed, false)]
[InlineData(WatcherChangeTypes.Renamed, true)]
[InlineData(WatcherChangeTypes.All, true)]
[InlineData(WatcherChangeTypes.Deleted, false, true)]
[InlineData(WatcherChangeTypes.Created, true, false)]
[InlineData(WatcherChangeTypes.Changed, false, true)]
[InlineData(WatcherChangeTypes.Renamed, true, false)]
[InlineData(WatcherChangeTypes.All, true, true)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58418", typeof(PlatformDetection), nameof(PlatformDetection.IsMacCatalyst), nameof(PlatformDetection.IsArm64Process))]
public void NonZeroTimeout_NoActivity_TimesOut(WatcherChangeTypes changeType, bool enabledBeforeWait)
public void NonZeroTimeout_NoActivity_TimesOut(WatcherChangeTypes changeType, bool enabledBeforeWait, bool useTimeSpan)
{
using (var testDirectory = new TempDirectory(GetTestFilePath()))
using (var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())))
using (var fsw = new FileSystemWatcher(testDirectory.Path))
{
if (enabledBeforeWait) fsw.EnableRaisingEvents = true;
AssertTimedOut(fsw.WaitForChanged(changeType, 1));
const int timeoutMilliseconds = 1;
AssertTimedOut(useTimeSpan
? fsw.WaitForChanged(changeType, TimeSpan.FromMilliseconds(timeoutMilliseconds))
: fsw.WaitForChanged(changeType, timeoutMilliseconds));
Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ public sealed partial class NamedPipeClientStream : System.IO.Pipes.PipeStream
protected internal override void CheckPipePropertyOperations() { }
public void Connect() { }
public void Connect(int timeout) { }
public void Connect(System.TimeSpan timeout) { }
public System.Threading.Tasks.Task ConnectAsync() { throw null; }
public System.Threading.Tasks.Task ConnectAsync(int timeout) { throw null; }
public System.Threading.Tasks.Task ConnectAsync(int timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
public System.Threading.Tasks.Task ConnectAsync(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
public System.Threading.Tasks.Task ConnectAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
~NamedPipeClientStream() { }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ public void Connect(int timeout)
ConnectInternal(timeout, CancellationToken.None, Environment.TickCount);
}

public void Connect(TimeSpan timeout) => Connect(ToTimeoutMilliseconds(timeout));

private void ConnectInternal(int timeout, CancellationToken cancellationToken, int startTime)
{
// This is the main connection loop. It will loop until the timeout expires.
Expand Down Expand Up @@ -193,6 +195,19 @@ public Task ConnectAsync(int timeout, CancellationToken cancellationToken)
return Task.Run(() => ConnectInternal(timeout, cancellationToken, startTime), cancellationToken);
}

public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken = default) =>
ConnectAsync(ToTimeoutMilliseconds(timeout), cancellationToken);

private static int ToTimeoutMilliseconds(TimeSpan timeout)
{
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(timeout));
}
return (int)totalMilliseconds;
}

// override because named pipe clients can't get/set properties when waiting to connect
// or broken
protected internal override void CheckPipePropertyOperations()
Expand Down
Loading