【发布时间】:2016-12-07 14:28:03
【问题描述】:
美好的一天。我与 UdpClient 合作并在其上进行了包装。
为了阅读,我有异步方法:
private async Task<byte[]> Receive(UdpClient client, CancellationToken breakToken)
{
// Выход из async, если произошёл CancellationRequest
breakToken.ThrowIfCancellationRequested();
UdpReceiveResult result;
try
{
result = await client.ReceiveAsync().WithCancellation(breakToken);
}
catch(OperationCanceledException)
{
// Штатная ситуация ручной остановки Task-а
}
return result.Buffer;
}
WithCancellation 是我提前终止的扩展方法:
public static async Task<T> WithCancellation<T>(
this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
using (cancellationToken.Register(
s => ((TaskCompletionSource<bool>)s).TrySetResult(true),
tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new OperationCanceledException(cancellationToken);
return await task;
}
手动读取停止后,当我调用Dispose 时,会出现System.ObjectDisposedException。 CallStack:
> System.dll!System.Net.Sockets.UdpClient.EndReceive(System.IAsyncResult asyncResult, ref System.Net.IPEndPoint remoteEP) Unknown
System.dll!System.Net.Sockets.UdpClient.ReceiveAsync.AnonymousMethod__64_1(System.IAsyncResult ar) Unknown
mscorlib.dll!System.Threading.Tasks.TaskFactory<System.Net.Sockets.UdpReceiveResult>.FromAsyncCoreLogic(System.IAsyncResult iar, System.Func<System.IAsyncResult, System.Net.Sockets.UdpReceiveResult> endFunction, System.Action<System.IAsyncResult> endAction, System.Threading.Tasks.Task<System.Net.Sockets.UdpReceiveResult> promise, bool requiresSynchronization) Unknown
mscorlib.dll!System.Threading.Tasks.TaskFactory<System.Net.Sockets.UdpReceiveResult>.FromAsyncImpl.AnonymousMethod__0(System.IAsyncResult iar) Unknown
System.dll!System.Net.LazyAsyncResult.Complete(System.IntPtr userToken) Unknown
System.dll!System.Net.ContextAwareResult.CompleteCallback(object state) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
System.dll!System.Net.ContextAwareResult.Complete(System.IntPtr userToken) Unknown
System.dll!System.Net.LazyAsyncResult.ProtectedInvokeCallback(object result, System.IntPtr userToken) Unknown
System.dll!System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* nativeOverlapped) Unknown
mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) Unknown
如果我理解正确,ReceiveAsync 中的错误根源,准确地说是我停止它的方法。但我不知道如何解决它。
我必须做些什么来纠正这个错误?
在 usr 评论后更新:
private async Task<byte[]> Receive(UdpClient client, CancellationToken breakToken)
{
// Выход из async, если произошёл CancellationRequest
breakToken.ThrowIfCancellationRequested();
UdpReceiveResult result;
try
{
result = await client.ReceiveAsync().WithCancellation(breakToken);
}
catch(OperationCanceledException)
{
// Штатная ситуация ручной остановки Task-а
}
catch(ObjectDisposedException) { }
return result.Buffer;
}
和Dispose 调用:
public void Dispose()
{
this.cancelRecieve?.Cancel();
this.cancelRecieve?.Dispose();
try
{
this.client?.Close();
}
catch(ObjectDisposedException) { }
}
但是catch 对ObjectDisposedException 没有反应。
【问题讨论】:
标签: c# asynchronous udpclient objectdisposedexception