namespace GSF.Net.Snmp.Messaging{ using System; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; internal sealed class SocketAwaitable : INotifyCompletion, IDisposable { private readonly static Action SENTINEL = () => { }; internal bool m_wasCompleted; internal Action m_continuation; internal SocketAsyncEventArgs m_eventArgs; private bool _disposed; public SocketAwaitable(SocketAsyncEventArgs eventArgs) { if (eventArgs == null) { throw new ArgumentNullException(nameof(eventArgs)); } m_eventArgs = eventArgs; m_eventArgs.Completed += Completed; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~SocketAwaitable() { Dispose(false); } private void Dispose(bool disposing) { if (_disposed) { return; } _disposed = true; if (disposing) { m_eventArgs.Completed -= Completed; SocketExtension.EventArgsFactory.Reuse(m_eventArgs); m_eventArgs = null; } } private void Completed(object sender, SocketAsyncEventArgs e) { (m_continuation ?? Interlocked.CompareExchange( ref m_continuation, SENTINEL, null))?.Invoke(); } internal void Reset() { m_wasCompleted = false; m_continuation = null; } public SocketAwaitable GetAwaiter() { return this; } public bool IsCompleted { get { return m_wasCompleted; } } public void OnCompleted(Action continuation) { if (m_continuation == SENTINEL || Interlocked.CompareExchange( ref m_continuation, continuation, null) == SENTINEL) { Task.Run(continuation); } } public int GetResult() { if (m_eventArgs.SocketError != SocketError.Success) throw new SocketException((int)m_eventArgs.SocketError); return m_eventArgs.BytesTransferred; } }}
namespace GSF.Net.Snmp.Messaging
{
using System;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
internal sealed class SocketAwaitable : INotifyCompletion, IDisposable
{
private readonly static Action SENTINEL = () => { };
internal bool m_wasCompleted;
internal Action m_continuation;
internal SocketAsyncEventArgs m_eventArgs;
private bool _disposed;
public SocketAwaitable(SocketAsyncEventArgs eventArgs)
{
if (eventArgs == null)
{
throw new ArgumentNullException(nameof(eventArgs));
}
m_eventArgs = eventArgs;
m_eventArgs.Completed += Completed;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~SocketAwaitable()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
_disposed = true;
if (disposing)
{
m_eventArgs.Completed -= Completed;
SocketExtension.EventArgsFactory.Reuse(m_eventArgs);
m_eventArgs = null;
}
}
private void Completed(object sender, SocketAsyncEventArgs e)
{
(m_continuation ?? Interlocked.CompareExchange(
ref m_continuation, SENTINEL, null))?.Invoke();
}
internal void Reset()
{
m_wasCompleted = false;
m_continuation = null;
}
public SocketAwaitable GetAwaiter() { return this; }
public bool IsCompleted { get { return m_wasCompleted; } }
public void OnCompleted(Action continuation)
{
if (m_continuation == SENTINEL ||
Interlocked.CompareExchange(
ref m_continuation, continuation, null) == SENTINEL)
{
Task.Run(continuation);
}
}
public int GetResult()
{
if (m_eventArgs.SocketError != SocketError.Success)
throw new SocketException((int)m_eventArgs.SocketError);
return m_eventArgs.BytesTransferred;
}
}
}