Added async support"
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# statsd-csharp-client Changelog
|
||||
|
||||
## v1.4.0.0
|
||||
* Added async support
|
||||
|
||||
## v1.3.0.0
|
||||
* Added support for Calendargrams
|
||||
|
||||
|
||||
42
StatsdClient/AsyncLock.cs
Normal file
42
StatsdClient/AsyncLock.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
internal sealed class AsyncLock
|
||||
{
|
||||
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
|
||||
private readonly Task<IDisposable> _releaser;
|
||||
|
||||
public AsyncLock()
|
||||
{
|
||||
_releaser = Task.FromResult((IDisposable)new Releaser(this));
|
||||
}
|
||||
|
||||
public Task<IDisposable> LockAsync()
|
||||
{
|
||||
var wait = _semaphore.WaitAsync();
|
||||
return wait.IsCompleted ?
|
||||
_releaser :
|
||||
wait.ContinueWith((_, state) => (IDisposable)state,
|
||||
_releaser.Result, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
private sealed class Releaser : IDisposable
|
||||
{
|
||||
private readonly AsyncLock _toRelease;
|
||||
|
||||
internal Releaser(AsyncLock toRelease)
|
||||
{
|
||||
_toRelease = toRelease;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_toRelease._semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
@@ -11,8 +8,8 @@ namespace StatsdClient
|
||||
public interface IOutputChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// Sends a line of stats data to the server.
|
||||
/// Sends a line of stats data to the server asynchronously.
|
||||
/// </summary>
|
||||
void Send(string line);
|
||||
Task SendAsync(string line);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
/// <summary>
|
||||
@@ -9,45 +10,47 @@ namespace StatsdClient
|
||||
/// <summary>
|
||||
/// Log a count for a metric
|
||||
/// </summary>
|
||||
void LogCount(string name, int count = 1);
|
||||
Task LogCountAsync(string name, long count = 1);
|
||||
|
||||
/// <summary>
|
||||
/// Log a gauge value
|
||||
/// </summary>
|
||||
void LogGauge(string name, int value);
|
||||
Task LogGaugeAsync(string name, long value);
|
||||
|
||||
/// <summary>
|
||||
/// Log a latency / Timing
|
||||
/// </summary>
|
||||
void LogTiming(string name, int milliseconds);
|
||||
/// <summary>
|
||||
/// Log a latency / Timing
|
||||
/// </summary>
|
||||
void LogTiming(string name, long milliseconds);
|
||||
Task LogTimingAsync(string name, long milliseconds);
|
||||
|
||||
/// <summary>
|
||||
/// Log the number of unique occurrances of something
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
void LogSet(string name, int value);
|
||||
Task LogSetAsync(string name, long value);
|
||||
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
void LogCalendargram(string name, string value, string period);
|
||||
Task LogCalendargramAsync(string name, string value, string period);
|
||||
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
void LogCalendargram(string name, int value, string period);
|
||||
Task LogCalendargramAsync(string name, long value, string period);
|
||||
|
||||
/// <summary>
|
||||
/// Log a raw metric that will not get aggregated on the server.
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="value">The metric value.</param>
|
||||
/// <param name="epoch">(optional) The epoch timestamp. Leave this blank to have the server assign an epoch for you.</param>
|
||||
void LogRaw(string name, int value, long? epoch = null);
|
||||
Task LogRawAsync(string name, long value, long? epoch = null);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
internal sealed class NullOutputChannel : IOutputChannel
|
||||
{
|
||||
public void Send(string line)
|
||||
public async Task SendAsync(string line)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
}
|
||||
}
|
||||
10
StatsdClient/OutputChannelExtensions.cs
Normal file
10
StatsdClient/OutputChannelExtensions.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace StatsdClient
|
||||
{
|
||||
public static class OutputChannelExtensions
|
||||
{
|
||||
public static void Send(this IOutputChannel outputChannel, string line)
|
||||
{
|
||||
outputChannel.SendAsync(line).Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
@@ -107,9 +105,9 @@ namespace StatsdClient
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="count">The counter value (defaults to 1).</param>
|
||||
public void LogCount(string name, int count = 1)
|
||||
public async Task LogCountAsync(string name, long count = 1)
|
||||
{
|
||||
SendMetric(MetricType.COUNT, name, _prefix, count);
|
||||
await SendMetricAsync(MetricType.COUNT, name, _prefix, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -117,19 +115,9 @@ namespace StatsdClient
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="milliseconds">The duration, in milliseconds, for this metric.</param>
|
||||
public void LogTiming(string name, int milliseconds)
|
||||
public async Task LogTimingAsync(string name, long milliseconds)
|
||||
{
|
||||
SendMetric(MetricType.TIMING, name, _prefix, milliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a timing / latency
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="milliseconds">The duration, in milliseconds, for this metric.</param>
|
||||
public void LogTiming(string name, long milliseconds)
|
||||
{
|
||||
LogTiming(name, (int)milliseconds);
|
||||
await SendMetricAsync(MetricType.TIMING, name, _prefix, milliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,9 +125,9 @@ namespace StatsdClient
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name</param>
|
||||
/// <param name="value">The value for this gauge</param>
|
||||
public void LogGauge(string name, int value)
|
||||
public async Task LogGaugeAsync(string name, long value)
|
||||
{
|
||||
SendMetric(MetricType.GAUGE, name, _prefix, value);
|
||||
await SendMetricAsync(MetricType.GAUGE, name, _prefix, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -147,33 +135,13 @@ namespace StatsdClient
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="value">The value to log.</param>
|
||||
/// <remarks>Logging to a set is about counting the number
|
||||
/// of occurrences of each event.</remarks>
|
||||
public void LogSet(string name, int value)
|
||||
/// <remarks>
|
||||
/// Logging to a set is about counting the number
|
||||
/// of occurrences of each event.
|
||||
/// </remarks>
|
||||
public async Task LogSetAsync(string name, long value)
|
||||
{
|
||||
SendMetric(MetricType.SET, name, _prefix, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
public void LogCalendargram(string name, string value, string period)
|
||||
{
|
||||
SendMetric(MetricType.CALENDARGRAM, name, _prefix, value, period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
public void LogCalendargram(string name, int value, string period)
|
||||
{
|
||||
SendMetric(MetricType.CALENDARGRAM, name, _prefix, value, period);
|
||||
await SendMetricAsync(MetricType.SET, name, _prefix, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -182,28 +150,50 @@ namespace StatsdClient
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="value">The metric value.</param>
|
||||
/// <param name="epoch">(optional) The epoch timestamp. Leave this blank to have the server assign an epoch for you.</param>
|
||||
public void LogRaw(string name, int value, long? epoch = null)
|
||||
public async Task LogRawAsync(string name, long value, long? epoch = null)
|
||||
{
|
||||
SendMetric(MetricType.RAW, name, String.Empty, value, epoch.HasValue ? epoch.ToString() : (string)null);
|
||||
await SendMetricAsync(MetricType.RAW, name, String.Empty, value, epoch.HasValue ? epoch.ToString() : null);
|
||||
}
|
||||
|
||||
private void SendMetric(string metricType, string name, string prefix, int value, string postFix = null)
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
public async Task LogCalendargramAsync(string name, string value, string period)
|
||||
{
|
||||
await SendMetricAsync(MetricType.CALENDARGRAM, name, _prefix, value, period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
public async Task LogCalendargramAsync(string name, long value, string period)
|
||||
{
|
||||
await SendMetricAsync(MetricType.CALENDARGRAM, name, _prefix, value, period);
|
||||
}
|
||||
|
||||
private async Task SendMetricAsync(string metricType, string name, string prefix, long value, string postFix = null)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
Trace.TraceWarning(String.Format("Metric value for {0} was less than zero: {1}. Not sending.", name, value));
|
||||
Trace.TraceWarning("Metric value for {0} was less than zero: {1}. Not sending.", name, value);
|
||||
return;
|
||||
}
|
||||
SendMetric(metricType, name, prefix, value.ToString(), postFix);
|
||||
await SendMetricAsync(metricType, name, prefix, value.ToString(), postFix);
|
||||
}
|
||||
|
||||
private void SendMetric(string metricType, string name, string prefix, string value, string postFix = null)
|
||||
private async Task SendMetricAsync(string metricType, string name, string prefix, string value, string postFix = null)
|
||||
{
|
||||
if (String.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
_outputChannel.Send(PrepareMetric(metricType, name, prefix, value, postFix));
|
||||
await _outputChannel.SendAsync(PrepareMetric(metricType, name, prefix, value, postFix));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -40,12 +40,14 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AsyncLock.cs" />
|
||||
<Compile Include="CalendargramRetentionPeriod.cs" />
|
||||
<Compile Include="ConnectionType.cs" />
|
||||
<Compile Include="IOutputChannel.cs" />
|
||||
<Compile Include="IStatsd.cs" />
|
||||
<Compile Include="MetricType.cs" />
|
||||
<Compile Include="NullOutputChannel.cs" />
|
||||
<Compile Include="OutputChannelExtensions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="StatsdExtensions.cs" />
|
||||
<Compile Include="Statsd.cs" />
|
||||
|
||||
@@ -1,14 +1,88 @@
|
||||
using StatsdClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
/// <summary>
|
||||
/// A set of extensions for use with the StatsdClient library.
|
||||
/// </summary>
|
||||
public static class StatsdClientExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Log a counter.
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="count">The counter value (defaults to 1).</param>
|
||||
public static void LogCount(this IStatsd client, string name, int count = 1)
|
||||
{
|
||||
client.LogCountAsync(name, count).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a timing / latency
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="milliseconds">The duration, in milliseconds, for this metric.</param>
|
||||
public static void LogTiming(this IStatsd client, string name, long milliseconds)
|
||||
{
|
||||
client.LogTimingAsync(name, milliseconds).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a gauge.
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name</param>
|
||||
/// <param name="value">The value for this gauge</param>
|
||||
public static void LogGauge(this IStatsd client, string name, int value)
|
||||
{
|
||||
client.LogGaugeAsync(name, value).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log to a set
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="value">The value to log.</param>
|
||||
/// <remarks>
|
||||
/// Logging to a set is about counting the number of occurrences of each event.
|
||||
/// </remarks>
|
||||
public static void LogSet(this IStatsd client, string name, int value)
|
||||
{
|
||||
client.LogSetAsync(name, value).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a raw metric that will not get aggregated on the server.
|
||||
/// </summary>
|
||||
/// <param name="name">The metric name.</param>
|
||||
/// <param name="value">The metric value.</param>
|
||||
/// <param name="epoch">(optional) The epoch timestamp. Leave this blank to have the server assign an epoch for you.</param>
|
||||
public static void LogRaw(this IStatsd client, string name, int value, long? epoch = null)
|
||||
{
|
||||
client.LogRawAsync(name, value, epoch).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
public static void LogCalendargram(this IStatsd client, string name, string value, string period)
|
||||
{
|
||||
client.LogCalendargramAsync(name, value, period).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a calendargram metric
|
||||
/// </summary>
|
||||
/// <param name="name">The metric namespace</param>
|
||||
/// <param name="value">The unique value to be counted in the time period</param>
|
||||
/// <param name="period">The time period, can be one of h,d,dow,w,m</param>
|
||||
public static void LogCalendargram(this IStatsd client, string name, long value, string period)
|
||||
{
|
||||
client.LogCalendargramAsync(name, value, period).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a timing metric
|
||||
/// </summary>
|
||||
@@ -17,7 +91,7 @@ public static class StatsdClientExtensions
|
||||
/// <param name="duration">The duration to log (will be converted into milliseconds)</param>
|
||||
public static void LogTiming(this IStatsd client, string name, TimeSpan duration)
|
||||
{
|
||||
client.LogTiming(name, (int)duration.TotalMilliseconds);
|
||||
client.LogTiming(name, (long)duration.TotalMilliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -26,10 +100,12 @@ public static class StatsdClientExtensions
|
||||
/// <param name="client">The statsd clien instance.</param>
|
||||
/// <param name="name">The namespace of the timing metric.</param>
|
||||
/// <returns>A timing token that has been initialised with a start datetime.</returns>
|
||||
/// <remarks>Wrap the code you want to measure in a using() {} block. The
|
||||
/// TimingToken instance will log the duration when it is disposed.</remarks>
|
||||
/// <remarks>
|
||||
/// Wrap the code you want to measure in a using() {} block. The TimingToken instance will log the duration when it is disposed.
|
||||
/// </remarks>
|
||||
public static TimingToken LogTiming(this IStatsd client, string name)
|
||||
{
|
||||
return new TimingToken(client, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
internal sealed class TcpOutputChannel : IOutputChannel
|
||||
{
|
||||
private TcpClient _tcpClient;
|
||||
private readonly TcpClient _tcpClient;
|
||||
private NetworkStream _stream;
|
||||
private object _reconnectLock;
|
||||
private string _host;
|
||||
private int _port;
|
||||
private bool _reconnectEnabled;
|
||||
private int _retryAttempts;
|
||||
private readonly string _host;
|
||||
private readonly int _port;
|
||||
private readonly bool _reconnectEnabled;
|
||||
private readonly int _retryAttempts;
|
||||
private readonly AsyncLock _asyncLock;
|
||||
|
||||
public TcpOutputChannel(string host, int port, bool reconnectEnabled = true, int retryAttempts = 3)
|
||||
{
|
||||
@@ -25,61 +24,64 @@ namespace StatsdClient
|
||||
_reconnectEnabled = reconnectEnabled;
|
||||
_retryAttempts = retryAttempts;
|
||||
_tcpClient = new TcpClient();
|
||||
_reconnectLock = new object();
|
||||
_asyncLock = new AsyncLock();
|
||||
}
|
||||
|
||||
public void Send(string line)
|
||||
public async Task SendAsync(string line)
|
||||
{
|
||||
SendWithRetry(line, _reconnectEnabled ? _retryAttempts - 1 : 0);
|
||||
await SendWithRetryAsync(line, _reconnectEnabled ? _retryAttempts - 1 : 0);
|
||||
}
|
||||
|
||||
private void SendWithRetry(string line, int attemptsLeft)
|
||||
private async Task SendWithRetryAsync(string line, int attemptsLeft)
|
||||
{
|
||||
string errorMessage = null;
|
||||
try
|
||||
{
|
||||
if (!_tcpClient.Connected)
|
||||
{
|
||||
RestoreConnection();
|
||||
await RestoreConnectionAsync();
|
||||
}
|
||||
|
||||
var bytesToSend = Encoding.UTF8.GetBytes(line + Environment.NewLine);
|
||||
_stream.Write( bytesToSend, 0, bytesToSend.Length );
|
||||
await _stream.WriteAsync(bytesToSend, 0, bytesToSend.Length);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
if ( attemptsLeft > 0 )
|
||||
{
|
||||
SendWithRetry( line, --attemptsLeft );
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more attempts left, so log it and continue
|
||||
Trace.TraceWarning( "Sending metrics via TCP failed with an IOException: {0}", ex.Message );
|
||||
}
|
||||
errorMessage = string.Format("Sending metrics via TCP failed with an IOException: {0}", ex.Message);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
// No more attempts left, so log it and continue
|
||||
errorMessage = string.Format("Sending metrics via TCP failed with a SocketException: {0}, code: {1}", ex.Message, ex.SocketErrorCode);
|
||||
}
|
||||
|
||||
if (errorMessage != null)
|
||||
{
|
||||
if (attemptsLeft > 0)
|
||||
{
|
||||
SendWithRetry( line, --attemptsLeft );
|
||||
await SendWithRetryAsync(line, --attemptsLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more attempts left, so log it and continue
|
||||
Trace.TraceWarning( "Sending metrics via TCP failed with a SocketException: {0}, code: {1}", ex.Message, ex.SocketErrorCode.ToString() );
|
||||
Trace.TraceWarning(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreConnection()
|
||||
{
|
||||
lock (_reconnectLock)
|
||||
private async Task RestoreConnectionAsync()
|
||||
{
|
||||
if (!_tcpClient.Connected)
|
||||
{
|
||||
_tcpClient.Connect(_host, _port);
|
||||
using (await _asyncLock.LockAsync())
|
||||
{
|
||||
if (!_tcpClient.Connected)
|
||||
{
|
||||
await _tcpClient.ConnectAsync(_host, _port);
|
||||
_stream = _tcpClient.GetStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsdClient
|
||||
{
|
||||
internal sealed class UdpOutputChannel : IOutputChannel
|
||||
{
|
||||
private UdpClient _udpClient;
|
||||
public Socket ClientSocket { get { return _udpClient.Client; } }
|
||||
private readonly UdpClient _udpClient;
|
||||
|
||||
public Socket ClientSocket
|
||||
{
|
||||
get
|
||||
{
|
||||
return _udpClient.Client;
|
||||
}
|
||||
}
|
||||
|
||||
public UdpOutputChannel(string hostOrIPAddress, int port)
|
||||
{
|
||||
@@ -25,10 +31,10 @@ namespace StatsdClient
|
||||
_udpClient.Connect(ipAddress, port);
|
||||
}
|
||||
|
||||
public void Send(string line)
|
||||
public async Task SendAsync(string line)
|
||||
{
|
||||
byte[] payload = Encoding.UTF8.GetBytes(line);
|
||||
_udpClient.Send(payload, payload.Length);
|
||||
var payload = Encoding.UTF8.GetBytes(line);
|
||||
await _udpClient.SendAsync(payload, payload.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user