<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" />
<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>
<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" />
AllocationExceeded = 3
}
- public static class GC
+ public static partial class GC
{
public static int GetGeneration(object obj)
{
{
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; }
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>
public string Pattern { get; }
<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" />
--- /dev/null
+// 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);
+ }
+ }
+}
namespace System.ComponentModel.DataAnnotations.Tests
{
- public class RegularExpressionAttributeTests : ValidationAttributeTestBase
+ public sealed partial class RegularExpressionAttributeTests : ValidationAttributeTestBase
{
protected override IEnumerable<TestCase> ValidValues()
{
{
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)]
}
/// <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.
/// </summary>
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
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>
}
/// <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.
/// </summary>
}
}
+ [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()
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
{
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>
}
[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);
}
}
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() { }
}
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.
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()
}
[OuterLoop]
- [ConditionalFact(nameof(IsAdminOnSupportedWindowsVersions))]
- public void Allow_Connection_UnderDifferentUsers_ForClientReading()
+ [ConditionalTheory(nameof(IsAdminOnSupportedWindowsVersions))]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void Allow_Connection_UnderDifferentUsers_ForClientReading(bool useTimeSpan)
{
string name = PipeStreamConformanceTests.GetUniquePipeName();
using (var server = new NamedPipeServerStream(
- name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
+ name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
Task serverTask = server.WaitForConnectionAsync(CancellationToken.None);
{
using (var client = new NamedPipeClientStream(".", name, PipeDirection.In))
{
- client.Connect(10_000);
+ if (useTimeSpan)
+ {
+ client.Connect(TimeSpan.FromMilliseconds(10_000));
+ }
+ else
+ {
+ client.Connect(10_000);
+ }
}
});
{
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => client.Connect(-111));
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { client.ConnectAsync(-111); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => client.Connect(TimeSpan.FromMilliseconds(-2)));
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds(-2), default); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => client.Connect(TimeSpan.FromMilliseconds((long)int.MaxValue + 1)));
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default); });
}
}
using (NamedPipeClientStream client = new NamedPipeClientStream(".", "notthere"))
{
var ctx = new CancellationTokenSource();
- Assert.Throws<TimeoutException>(() => client.Connect(60)); // 60 to be over internal 50 interval
- await Assert.ThrowsAsync<TimeoutException>(() => client.ConnectAsync(50));
- await Assert.ThrowsAsync<TimeoutException>(() => client.ConnectAsync(60, ctx.Token)); // testing Token overload; ctx is not canceled in this test
+ Assert.Throws<TimeoutException>(() =>
+ client.Connect(TimeSpan.FromMilliseconds(60))); // 60 to be over internal 50 interval
+ await Assert.ThrowsAsync<TimeoutException>(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50), default));
+ await Assert.ThrowsAsync<TimeoutException>(() =>
+ client.ConnectAsync(TimeSpan.FromMilliseconds(60),
+ ctx.Token)); // testing Token overload; ctx is not canceled in this test
}
}
string pipeName = PipeStreamConformanceTests.GetUniquePipeName();
using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName))
{
- Task waitingClient = client.ConnectAsync(92, cancellationToken);
+ TimeSpan timeout = TimeSpan.FromMilliseconds(92);
+ Task waitingClient = client.ConnectAsync(timeout, cancellationToken);
await Assert.ThrowsAsync<TimeoutException>(() => { return waitingClient; });
}
}
using (NamedPipeClientStream firstClient = new NamedPipeClientStream(pipeName))
using (NamedPipeClientStream secondClient = new NamedPipeClientStream(pipeName))
{
- const int timeout = 10_000;
+ var ctx = new CancellationTokenSource();
+ TimeSpan timeout = TimeSpan.FromMilliseconds(10_000);
Task[] clientAndServerTasks = new[]
{
- firstClient.ConnectAsync(timeout),
+ firstClient.ConnectAsync(timeout, ctx.Token),
Task.Run(() => server.WaitForConnection())
};
Assert.True(Task.WaitAll(clientAndServerTasks, timeout));
- Assert.Throws<TimeoutException>(() => secondClient.Connect(93));
+ TimeSpan connectionTimeout = TimeSpan.FromMilliseconds(93);
+ Assert.Throws<TimeoutException>(() => secondClient.Connect(connectionTimeout));
}
}
using (NamedPipeClientStream firstClient = new NamedPipeClientStream(pipeName))
using (NamedPipeClientStream secondClient = new NamedPipeClientStream(pipeName))
{
- const int timeout = 10_000;
+ TimeSpan timeout = TimeSpan.FromMilliseconds(10_000);
Task[] clientAndServerTasks = new[]
{
- firstClient.ConnectAsync(timeout),
+ firstClient.ConnectAsync(timeout, cancellationToken),
Task.Run(() => server.WaitForConnection())
};
Assert.True(Task.WaitAll(clientAndServerTasks, timeout));
- Task waitingClient = secondClient.ConnectAsync(94, cancellationToken);
+ TimeSpan connectionTimeout = TimeSpan.FromMilliseconds(94);
+ Task waitingClient = secondClient.ConnectAsync(connectionTimeout, cancellationToken);
await Assert.ThrowsAsync<TimeoutException>(() => { return waitingClient; });
}
}
public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout) { throw null; }
public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer) { throw null; }
public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
+ public System.Net.NetworkInformation.PingReply Send(System.Net.IPAddress address, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
+ public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options, object? userToken) { }
public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, object? userToken) { }
public void SendAsync(System.Net.IPAddress address, int timeout, object? userToken) { }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, int timeout) { throw null; }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer) { throw null; }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
+ public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(System.Net.IPAddress address, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options, System.Threading.CancellationToken cancellationToken) { throw null; }
+ public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options, System.Threading.CancellationToken cancellationToken) { throw null; }
}
public partial class PingCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
}
}
+ public PingReply Send(IPAddress address, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null) =>
+ Send(address, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options);
+
+ public PingReply Send(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null,
+ PingOptions? options = null) => Send(hostNameOrAddress, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options);
+
public void SendAsync(string hostNameOrAddress, object? userToken)
{
SendAsync(hostNameOrAddress, DefaultTimeout, DefaultSendBuffer, userToken);
return SendPingAsyncInternal(address, timeout, buffer, options);
}
+ public Task<PingReply> SendPingAsync(IPAddress address, TimeSpan timeout, byte[]? buffer = null,
+ PingOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+ Task<PingReply> task = SendPingAsync(address, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options);
+
+ return task.WaitAsync(cancellationToken);
+ }
+
+ public Task<PingReply> SendPingAsync(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null,
+ PingOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+ Task<PingReply> task = SendPingAsync(hostNameOrAddress, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options);
+
+ return task.WaitAsync(cancellationToken);
+ }
+
private async Task<PingReply> SendPingAsyncInternal(IPAddress address, int timeout, byte[] buffer, PingOptions? options)
{
// Need to snapshot the address here, so we're sure that it's not changed between now
return GetAddressAndSendAsync(hostNameOrAddress, timeout, buffer, options);
}
+ 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;
+ }
+
public void SendAsyncCancel()
{
lock (_lockObject)
using Microsoft.DotNet.XUnitExtensions;
using System.Diagnostics;
+using System.Globalization;
using System.Linq;
using System.Net.Sockets;
using System.Net.Test.Common;
private void PingResultValidator(PingReply pingReply, IPAddress[] localIpAddresses) => PingResultValidator(pingReply, localIpAddresses, null);
- private static void PingResultValidator(PingReply pingReply, IPAddress[] localIpAddresses, ITestOutputHelper output)
+ private static void PingResultValidator(PingReply pingReply, IPAddress[] localIpAddresses, ITestOutputHelper? output)
{
Assert.Equal(IPStatus.Success, pingReply.Status);
if (localIpAddresses.Any(addr => pingReply.Address.Equals(addr)))
// Negative timeout
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(localIpAddress, -1); });
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, -1); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(localIpAddress, TimeSpan.FromMilliseconds(-1), default, default, default); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1), default, default, default); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(localIpAddress, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default, default); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default, default); });
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendAsync(localIpAddress, -1, null); });
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.SendAsync(TestSettings.LocalHost, -1, null); });
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.Send(localIpAddress, -1); });
AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.Send(TestSettings.LocalHost, -1); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.Send(localIpAddress, TimeSpan.FromMilliseconds(-1), default, default); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.Send(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1), default, default); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.Send(localIpAddress, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default); });
+ AssertExtensions.Throws<ArgumentOutOfRangeException>("timeout", () => { p.Send(TestSettings.LocalHost, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default); });
// Null byte[]
AssertExtensions.Throws<ArgumentNullException>("buffer", () => { p.SendPingAsync(localIpAddress, 0, null); });
public void SendPingAsync_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL)
{
IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily);
- if (localIpAddress == null)
- {
- // No local address for given address family.
- return;
- }
-
- var remoteInvokeStartInfo = new ProcessStartInfo();
- remoteInvokeStartInfo.EnvironmentVariables["LANG"] = envVar_LANG;
- remoteInvokeStartInfo.EnvironmentVariables["LC_MESSAGES"] = envVar_LC_MESSAGES;
- remoteInvokeStartInfo.EnvironmentVariables["LC_ALL"] = envVar_LC_ALL;
+ var remoteInvokeStartInfo = new ProcessStartInfo {
+ EnvironmentVariables =
+ {
+ ["LANG"] = envVar_LANG,
+ ["LC_MESSAGES"] = envVar_LC_MESSAGES,
+ ["LC_ALL"] = envVar_LC_ALL
+ }
+ };
RemoteExecutor.Invoke(async address =>
{
public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; }
public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; }
public void Close(int timeout) { }
+ public void Close(System.TimeSpan timeout) { }
protected override void Dispose(bool disposing) { }
public override int EndRead(System.IAsyncResult asyncResult) { throw null; }
public override void EndWrite(System.IAsyncResult asyncResult) { }
public void Listen() { }
public void Listen(int backlog) { }
public bool Poll(int microSeconds, System.Net.Sockets.SelectMode mode) { throw null; }
+ public bool Poll(System.TimeSpan timeout, System.Net.Sockets.SelectMode mode) { throw null; }
public int Receive(byte[] buffer) { throw null; }
public int Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags) { throw null; }
public int Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) { throw null; }
public System.Threading.Tasks.ValueTask<System.Net.Sockets.SocketReceiveMessageFromResult> ReceiveMessageFromAsync(System.Memory<byte> buffer, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint remoteEndPoint, System.Threading.CancellationToken cancellationToken = default) { throw null; }
public bool ReceiveMessageFromAsync(System.Net.Sockets.SocketAsyncEventArgs e) { throw null; }
public static void Select(System.Collections.IList? checkRead, System.Collections.IList? checkWrite, System.Collections.IList? checkError, int microSeconds) { }
+ public static void Select(System.Collections.IList? checkRead, System.Collections.IList? checkWrite, System.Collections.IList? checkError, System.TimeSpan timeout) { }
public int Send(byte[] buffer) { throw null; }
public int Send(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags) { throw null; }
public int Send(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) { throw null; }
Dispose();
}
+ public void Close(TimeSpan timeout) => Close(ToTimeoutSeconds(timeout));
+
+ private static int ToTimeoutSeconds(TimeSpan timeout)
+ {
+ long totalSeconds = (long)timeout.TotalSeconds;
+ if (totalSeconds < -1 || totalSeconds > int.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(timeout));
+ }
+ return (int)totalSeconds;
+ }
+
protected override void Dispose(bool disposing)
{
if (Interlocked.Exchange(ref _disposed, 1) != 0)
return status;
}
+ public bool Poll(TimeSpan timeout, SelectMode mode) =>
+ Poll(ToTimeoutMicroseconds(timeout), mode);
+
// Determines the status of a socket.
public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, int microSeconds)
{
}
}
+ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) => Select(checkRead, checkWrite, checkError, ToTimeoutMicroseconds(timeout));
+
+ private static int ToTimeoutMicroseconds(TimeSpan timeout)
+ {
+ long totalMicroseconds = timeout.Ticks / 10;
+ if (totalMicroseconds < -1 || totalMicroseconds > int.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(timeout));
+ }
+ return (int)totalMicroseconds;
+ }
+
public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) =>
TaskToApm.Begin(ConnectAsync(remoteEP), callback, state);
}
[Fact]
+ public void Select_NullOrEmptyLists_Throws_ArgumentNull_TimeSpan()
+ {
+ TimeSpan nonInfinity = TimeSpan.FromMilliseconds(1);
+ var emptyList = new List<Socket>();
+
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(null, null, null, nonInfinity));
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(emptyList, null, null, nonInfinity));
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(null, emptyList, null, nonInfinity));
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(emptyList, emptyList, null, nonInfinity));
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(null, null, emptyList, nonInfinity));
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(emptyList, null, emptyList, nonInfinity));
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(null, emptyList, emptyList, nonInfinity));
+ Assert.Throws<ArgumentNullException>(() => Socket.Select(emptyList, emptyList, emptyList, nonInfinity));
+ }
+
+ [Fact]
public void Select_LargeList_Throws_ArgumentOutOfRange()
{
var largeList = new LargeList();
}
[Fact]
+ public void Select_LargeList_Throws_ArgumentOutOfRange_TimeSpan()
+ {
+ var largeList = new LargeList();
+
+ TimeSpan infinity = Timeout.InfiniteTimeSpan;
+ Assert.Throws<ArgumentOutOfRangeException>(() => Socket.Select(largeList, null, null, infinity));
+ Assert.Throws<ArgumentOutOfRangeException>(() => Socket.Select(null, largeList, null, infinity));
+ Assert.Throws<ArgumentOutOfRangeException>(() => Socket.Select(null, null, largeList, infinity));
+
+ TimeSpan negative = TimeSpan.FromMilliseconds(-1);
+ Assert.Throws<ArgumentOutOfRangeException>(() => Socket.Select(largeList, null, null, negative));
+ Assert.Throws<ArgumentOutOfRangeException>(() => Socket.Select(null, largeList, null, negative));
+ Assert.Throws<ArgumentOutOfRangeException>(() => Socket.Select(null, null, largeList, negative));
+ }
+
+ [Fact]
public void AcceptAsync_NullAsyncEventArgs_Throws_ArgumentNull()
{
Assert.Throws<ArgumentNullException>(() => GetSocket().AcceptAsync((SocketAsyncEventArgs)null));
}
}
- [Fact]
- public async Task FailedConnect_ConnectedReturnsFalse()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public async Task FailedConnect_ConnectedReturnsFalse(bool useTimeSpan)
{
using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Assert.Equal(SocketError.WouldBlock, se.SocketErrorCode);
// Give the non-blocking connect some time to complete.
- socket.Poll(5_000_000 /* microSeconds */, SelectMode.SelectWrite);
+ if (useTimeSpan)
+ {
+ socket.Poll(TimeSpan.FromMilliseconds(5000), SelectMode.SelectWrite);
+ }
+ else
+ {
+ socket.Poll(5_000_000 /* microSeconds */, SelectMode.SelectWrite);
+ }
}
Assert.False(socket.Connected);
<Compile Include="$(MSBuildThisFileDirectory)System\FormatException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\FormattableString.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Function.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\GC.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\GCMemoryInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Gen2GcCallback.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Calendar.cs" />
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Threading;
+
+namespace System
+{
+ public static partial class GC
+ {
+ /// <summary>
+ /// Returns, in a specified time-out period, the status of a registered notification for determining whether a full,
+ /// blocking garbage collection by the common language runtime is imminent.
+ /// </summary>
+ /// <param name="timeout">The timeout on waiting for a full GC approach</param>
+ /// <returns>The status of a registered full GC notification</returns>
+ public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout)
+ => WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout));
+
+ /// <summary>
+ /// Returns the status of a registered notification about whether a blocking garbage collection
+ /// has completed. May wait indefinitely for a full collection.
+ /// </summary>
+ /// <param name="timeout">The timeout on waiting for a full collection</param>
+ /// <returns>The status of a registered full GC notification</returns>
+ public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout)
+ => WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout));
+ }
+}
/// infinite time-out -or- timeout is greater than
/// <see cref="int.MaxValue"/>.
/// </exception>
- public bool Wait(TimeSpan timeout)
+ public bool Wait(TimeSpan timeout) => Wait(timeout, default);
+
+ /// <summary>
+ /// Waits for the <see cref="Task"/> to complete execution.
+ /// </summary>
+ /// <param name="timeout">The time to wait, or <see cref="Timeout.InfiniteTimeSpan"/> to wait indefinitely</param>
+ /// <param name="cancellationToken">
+ /// A <see cref="CancellationToken"/> to observe while waiting for the task to complete.
+ /// </param>
+ /// <returns>
+ /// true if the <see cref="Task"/> completed execution within the allotted time; otherwise, false.
+ /// </returns>
+ /// <exception cref="AggregateException">
+ /// The <see cref="Task"/> was canceled -or- an exception was thrown during the execution of the <see
+ /// cref="Task"/>.
+ /// </exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="timeout"/> is a negative number other than -1 milliseconds, which represents an
+ /// infinite time-out -or- timeout is greater than
+ /// <see cref="int.MaxValue"/>.
+ /// </exception>
+ /// <exception cref="OperationCanceledException">
+ /// The <paramref name="cancellationToken"/> was canceled.
+ /// </exception>
+ public bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.timeout);
}
- return Wait((int)totalMilliseconds, default);
+ return Wait((int)totalMilliseconds, cancellationToken);
}
/// <summary>
public static bool TryStartNoGCRegion(long totalSize, long lohSize, bool disallowFullBlockingGC) { throw null; }
public static System.GCNotificationStatus WaitForFullGCApproach() { throw null; }
public static System.GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout) { throw null; }
+ public static System.GCNotificationStatus WaitForFullGCApproach(System.TimeSpan timeout) { throw null; }
public static System.GCNotificationStatus WaitForFullGCComplete() { throw null; }
public static System.GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout) { throw null; }
+ public static System.GCNotificationStatus WaitForFullGCComplete(System.TimeSpan timeout) { throw null; }
public static void WaitForPendingFinalizers() { }
}
public enum GCCollectionMode
public bool Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
public void Wait(System.Threading.CancellationToken cancellationToken) { }
public bool Wait(System.TimeSpan timeout) { throw null; }
+ public bool Wait(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
public static void WaitAll(params System.Threading.Tasks.Task[] tasks) { }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
namespace System.ServiceProcess
{
+ public partial class ServiceBase : System.ComponentModel.Component
+ {
+ public void RequestAdditionalTime(System.TimeSpan time) { }
+ }
public partial class ServiceController : System.ComponentModel.Component
{
public void Stop(bool stopDependentServices) { }
}
}
+#if NETCOREAPP
+ /// <summary>
+ /// When this method is called from OnStart, OnStop, OnPause or OnContinue,
+ /// the specified wait hint is passed to the
+ /// Service Control Manager to avoid having the service marked as not responding.
+ /// </summary>
+ /// <param name="time">The requested additional time</param>
+ public void RequestAdditionalTime(TimeSpan time) => RequestAdditionalTime(ToIntMilliseconds(time));
+
+ private static int ToIntMilliseconds(TimeSpan time)
+ {
+ long totalMilliseconds = (long)time.TotalMilliseconds;
+ if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(time));
+ }
+ return (int)totalMilliseconds;
+ }
+#endif
+
/// <summary>
/// Indicates whether to report Start, Stop, Pause, and Continue commands in the event.
/// </summary>
}
}
+#if NETCOREAPP
+ [Theory]
+ [InlineData(-2)]
+ [InlineData((long)int.MaxValue + 1)]
+ public void RequestAdditionalTime_Throws_ArgumentOutOfRangeException(long milliseconds)
+ {
+ TimeSpan time = TimeSpan.FromMilliseconds(milliseconds);
+ using var serviceBase = new ServiceBase();
+ Assert.Throws<ArgumentOutOfRangeException>("time", () => serviceBase.RequestAdditionalTime(time));
+ }
+#endif
+
[ConditionalFact(nameof(IsProcessElevated))]
public void TestOnStartThenStop()
{
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Helpers.cs" />
+ <Compile Include="Task\TaskArgumentValidationTests.cs" />
<Compile Include="XunitAssemblyAttributes.cs" />
<Compile Include="UnwrapTests.cs" />
<Compile Include="AggregateExceptionTests.cs" />
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Xunit;
+
+namespace System.Threading.Tasks.Tests
+{
+ public sealed class TaskArgumentValidationTests
+ {
+ [Theory]
+ [InlineData(-2)]
+ [InlineData((long)int.MaxValue + 1)]
+ public void Task_Wait_ArgumentOutOfRange(long milliseconds)
+ {
+ TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds);
+ Task task = Task.Run(static () => {});
+ Assert.Throws<ArgumentOutOfRangeException>("timeout", () => task.Wait(timeout));
+ }
+ }
+}
}
// Test what happens when you cancel a task in the middle of a continuation chain.
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
- public static void RunContinuationCancelTest()
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
+ [InlineData(false)]
+ [InlineData(true)]
+ public static void RunContinuationCancelTest(bool useTimeSpan)
{
bool t1Ran = false;
bool t3Ran = false;
CancellationTokenSource ctsForT2 = new CancellationTokenSource();
Task t2 = t1.ContinueWith((ContinuedTask) =>
- {
- Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t2 should not have run."));
- }, ctsForT2.Token);
+ {
+ Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t2 should not have run."));
+ }, ctsForT2.Token);
Task t3 = t2.ContinueWith((ContinuedTask) =>
{
// Start the first task in the chain. Should hold off from kicking off (canceled) t2.
t1.Start();
- t1.Wait(5000); // should be more than enough time for either of these
- t3.Wait(5000);
+ if (useTimeSpan)
+ {
+ TimeSpan timeout = TimeSpan.FromMilliseconds(5000);
+ t1.Wait(timeout);
+ t3.Wait(timeout);
+ }
+ else
+ {
+ t1.Wait(5000); // should be more than enough time for either of these
+ t3.Wait(5000);
+ }
if (!t1Ran)
{