Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 句柄无效-取消令牌源_C#_Cancellation - Fatal编程技术网

C# 句柄无效-取消令牌源

C# 句柄无效-取消令牌源,c#,cancellation,C#,Cancellation,从前,当调用CancellationTokenSourceCancel()方法时,我得到一个异常:句柄无效 at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.Threading.EventWaitHandle.Set() at System.Threading.CancellationTokenSource.NotifyCancellation(Boolean thr

从前,当调用
CancellationTokenSource
Cancel()
方法时,我得到一个异常:
句柄无效

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.Threading.EventWaitHandle.Set()
   at System.Threading.CancellationTokenSource.NotifyCancellation(Boolean throwOnFirstException)
   at System.Threading.CancellationTokenSource.Cancel()
   at .CancelProcess(Object obj) in proj\ViewModels\WorkflowContainerViewModel.cs:line 162
   at DelegateCommand.Execute(Object parameter) in proj\Commands\DelegateCommand.cs:line 32
   at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
   at System.Windows.Controls.Primitives.ButtonBase.OnClick()
   at System.Windows.Controls.Button.OnClick()
   at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
我到处都找不到任何东西。有什么想法吗?

问题(如注释中所述)是
CancellationToken
正在序列化,然后再次反序列化

CancellationTokenSource
(如果您直接实例化它,将创建一个
CancellationToken
)保存对非托管内核事件的引用(使用
EventWaitHandle
),并在内部保存对该句柄的引用

CancellationTokenSource
被释放时,它将释放该非托管引用。。。因此,如果序列化令牌,它将使用该句柄序列化。。。之后,您不再使用
CancellationTokenSource
,因此垃圾收集器会收集它,并释放内核事件(因此句柄不再有效)

现在,在反序列化时,
EventWaitHandle
将返回值,但它不会再次创建内核事件(因为在反序列化时,您只将值分配给字段,而不会再次执行构造逻辑),但它保留了旧的句柄。。。因此,当您想要取消它时,它将尝试使用不再有效的内核事件句柄:因此,您的异常

可能的解决办法:

  • 不要序列化/反序列化
    CancellationToken
    。。。相反,在反序列化时构造另一个
  • 如果这是不可能的(因为您需要使用这一个,而不能使用另一个),那么将
    CancellationTokenSource
    的引用保留在某个地方,这样它就不会被垃圾收集,也不会释放内核事件,所以在反序列化时句柄仍然有效

  • 想要关闭它的人-请让我知道原因是什么看到堆栈跟踪,我能够找到这个问题的解决方案,并且在您的代码中发现了15个其他错误,.NET framework中发现了3个,WPF中发现了4个。酷,我想不出还有什么其他重要的东西可以在这里展示。我正在调用cts.Cancel(),这是stacktrace。你想让我展示什么?您可以从stacktrace中看到它是从绑定到命令的wpf控件调用的,但我看不出为什么它会很重要。Zbignew,当您尝试对内核事件已被释放(其句柄丢失)的
    CancellationTokenSource执行某些操作时,就会出现
    无效句柄
    问题。正常使用时不应发生这种情况,但如果您正在序列化和反序列化它,则可能会发生这种情况(在反序列化后,原始对象将丢失,内核事件将被释放,并尝试设置相同的本机句柄,但该句柄不存在)。出现这种情况的原因有几个:如果没有一个最小的可复制示例,根本无法帮助您提到问题中提到的可能比堆栈跟踪更有效:-)如果您找到原因,请告诉我们