internal bool _accessed = false;
internal TaskSocketAsyncEventArgs() :
- base(flowExecutionContext: false) // avoid flowing context at lower layers as we only expose Task, which handles it
+ base(unsafeSuppressExecutionContextFlow: true) // avoid flowing context at lower layers as we only expose Task, which handles it
{
}
/// <summary>Initializes the event args.</summary>
public AwaitableSocketAsyncEventArgs() :
- base(flowExecutionContext: false) // avoid flowing context at lower layers as we only expose ValueTask, which handles it
+ base(unsafeSuppressExecutionContextFlow: true) // avoid flowing context at lower layers as we only expose ValueTask, which handles it
{
}
private MultipleConnectAsync _multipleConnect;
- public SocketAsyncEventArgs() : this(flowExecutionContext: true)
+ public SocketAsyncEventArgs() : this(unsafeSuppressExecutionContextFlow: false)
{
}
/// <summary>Initialize the SocketAsyncEventArgs</summary>
- /// <param name="flowExecutionContext">
- /// Whether to capture and flow ExecutionContext. ExecutionContext flow should only
+ /// <param name="unsafeSuppressExecutionContextFlow">
+ /// Whether to disable the capturing and flow of ExecutionContext. ExecutionContext flow should only
/// be disabled if it's going to be handled by higher layers.
/// </param>
- internal SocketAsyncEventArgs(bool flowExecutionContext)
+ public SocketAsyncEventArgs(bool unsafeSuppressExecutionContextFlow)
{
- _flowExecutionContext = flowExecutionContext;
+ _flowExecutionContext = !unsafeSuppressExecutionContextFlow;
InitializeInternals();
}
}
[Fact]
+ public async Task ExecutionContext_SocketAsyncEventArgs_Ctor_Default_FlowIsNotSuppressed()
+ {
+ await ExecutionContext_SocketAsyncEventArgs_Ctors(() => new SocketAsyncEventArgs(), false);
+ }
+
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task ExecutionContext_SocketAsyncEventArgs_Ctor_UnsafeSuppressExecutionContextFlow(bool suppressed)
+ {
+ await ExecutionContext_SocketAsyncEventArgs_Ctors(() => new SocketAsyncEventArgs(suppressed), suppressed);
+ }
+
+ private async Task ExecutionContext_SocketAsyncEventArgs_Ctors(Func<SocketAsyncEventArgs> saeaFactory, bool suppressed)
+ {
+ using (var listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+ using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+ {
+ listen.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+ listen.Listen(1);
+
+ Task<Socket> acceptTask = listen.AcceptAsync();
+ await Task.WhenAll(
+ acceptTask,
+ client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)listen.LocalEndPoint).Port)));
+
+ using (Socket server = await acceptTask)
+ using (SocketAsyncEventArgs receiveSaea = saeaFactory())
+ {
+ var local = new AsyncLocal<int>
+ {
+ Value = 42
+ };
+ int threadId = Environment.CurrentManagedThreadId;
+
+ var mres = new ManualResetEventSlim();
+ receiveSaea.SetBuffer(new byte[1], 0, 1);
+ receiveSaea.Completed += delegate
+ {
+ Assert.NotEqual(threadId, Environment.CurrentManagedThreadId);
+ Assert.Equal(suppressed ? 0 : 42, local.Value);
+ mres.Set();
+ };
+
+ Assert.True(client.ReceiveAsync(receiveSaea));
+ server.Send(new byte[1]);
+ mres.Wait();
+ }
+ }
+ }
+
+ [Fact]
public void SetBuffer_InvalidArgs_Throws()
{
using (var saea = new SocketAsyncEventArgs())
var args = new SocketAsyncEventArgs();
args.SetBuffer(new byte[1024], 0, 1024);
- args.Completed += (_,__) => tcs.SetResult(true);
+ args.Completed += (_, __) => tcs.SetResult(true);
for (int i = 1; i <= 10; i++)
{
sendBufferList.Add(new ArraySegment<byte>(sendBuffer, 0, 1));
var sendArgs = new SocketAsyncEventArgs();
sendArgs.BufferList = sendBufferList;
- sendArgs.Completed += (_,__) => tcs.SetResult(true);
+ sendArgs.Completed += (_, __) => tcs.SetResult(true);
var recvBuffer = new byte[64];
var recvBufferList = new List<ArraySegment<byte>>();
recvBufferList.Add(new ArraySegment<byte>(recvBuffer, 0, 1));
var recvArgs = new SocketAsyncEventArgs();
recvArgs.BufferList = recvBufferList;
- recvArgs.Completed += (_,__) => tcs.SetResult(true);
+ recvArgs.Completed += (_, __) => tcs.SetResult(true);
for (int i = 1; i <= 10; i++)
{