這是我用來 ping IP 地址串列的代碼。除了今天我收到一個致命的未處理例外之外,它作業正常!- System.ObjectDisposedException
private static CancellationTokenSource cts = new CancellationTokenSource();
private static CancellationToken ct;
// Source per cancellation Token
ct = cts.Token;
IsRun = true;
try
{
LoopAndCheckPingAsync(AddressList.Select(a => a.IP).ToList()).ContinueWith((t) =>
{
if (t.IsFaulted)
{
Exception ex = t.Exception;
while (ex is AggregateException && ex.InnerException != null)
ex = ex.InnerException;
Global.LOG.Log("Sonar.Start() - ContinueWith Faulted:" ex.Message);
}
else
{
// Cancellation tokek
if (cts != null)
{
cts.Dispose();
}
}
});
}
catch (Exception ex)
{
Global.LOG.Log("Sonar.Start() - Exc:" ex.Message);
}
由于我無法復制錯誤,我懷疑與 CancellationTokenSource 的 Disponse 方法有關。正確處理 CancellationTokenSource 的任何想法?
我采用了事件查看器詳細資訊條目:
Informazioni sull'eccezione: System.ObjectDisposedException
in System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean ByRef)
in System.StubHelpers.StubHelpers.SafeHandleAddRef(System.Runtime.InteropServices.SafeHandle, Boolean ByRef)
in Microsoft.Win32.Win32Native.SetEvent(Microsoft.Win32.SafeHandles.SafeWaitHandle)
in System.Threading.EventWaitHandle.Set()
in System.Net.NetworkInformation.Ping.set_InAsyncCall(Boolean)
in System.Net.NetworkInformation.Ping.Finish(Boolean)
in System.Net.NetworkInformation.Ping.PingCallback(System.Object, Boolean)
in System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context(System.Object, Boolean)
in System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context_f(System.Object)
in System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
in System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
in System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)
uj5u.com熱心網友回復:
無法從您發布的代碼中判斷錯誤的來源。通常,您必須檢查接收訊息(呼叫堆疊)以了解觸發例外的確切位置。
Dispose請求取消或可取消操作完成后呼叫。當您訪問 mutating 成員CancellationTokenSource或其CancellationToken實體時,會拋出例外CancellationTokenSource。就像呼叫Cancel已處理的實體或嘗試在呼叫CancellationToken后獲取對關聯的參考時一樣Dispose。您必須確保沒有代碼訪問已處理的實體。
您可以通過在處理時將 ??CancellationTokenSource 屬性設定為 null 并在訪問CancellationTokenSource. 你必須CancellationTokenSource小心地控制生命周期。
以下示例展示了如何控制CancellationTokenSource已處置實體的生命周期并防止非法參考:
private CancellationTokenSource CancellationtokenSource { get; set; }
private void CancelCancellableOperation_OnClick(object sender, EventArgs e)
{
// Check for null to avoid an ObjectDisposedException
// (or a NullReferenceException in particular) exception.
// The implemented pattern sets the property to null immediately after disposal (not thread-safe).
this.CancellationTokenSource?.Cancel();
}
// Start scope of CancellationTokenSource.
// Lifetime is managed by a try-catch-finally block and the use of
// CancellationToken.ThrowIfCancellationRequested
// to forcefully enter the try-catch-finally block on cancellation.
private async Task DoWorkAsync()
{
this.CancellationTokenSource = new CancellationTokenSource();
try
{
await CancellableOperationAsync(this.CancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
// Do some cleanup or rollback.
// At this point the CancellationTokenSource is still not disposed.
}
finally
{
// Invalidate CancellationTokenSource property to raise an NullReferenceException exception
// to indicate that thet access ocurred uncontrolled and requires a fix.
// Create a local copy of the property to avoid race conditions.
var cancellationTokenSource = this.CancellationTokenSource;
this.CancellationTokenSource = null;
// Dispose after cancellation
// or cancellable operations are completed
cancellationTokenSource.Dispose();
}
}
private async Task CancellableOperationAsync(CancellationToken cancellationToken)
{
// Guarantee that CancellationTokenSource is never disposed before
// CancellationTokenSource.Cancel was called or the cancellable operation has completed
// Do something
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(10));
// Add null check if you can't guarantee premature disposal
cancellationToken?.ThrowIfCancellationRequested();
}
}
uj5u.com熱心網友回復:
解決您的問題的最簡單方法是不處理 Cancellation 令牌源。
根據 MS 和一些帖子,只有當它是一個Linked cancellation token source或(這里我不完全確定)是否有令牌的Register方法分配的東西時,才需要處理取消令牌源。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/372183.html
上一篇:不禁止私人二傳手的訪問
