Removing the Console.CancelKeyPress handler disables any subsequent processing.

I am making an interactive benchmarking program that works in console mode and would like to interrupt the current calculations by pressing Ctrl + C or Ctrl + Break once, and the next press should act as usual, ending the program. However, when no calculation is currently in progress, the very first press of Ctrl + C should complete.

At first it looked like a simple task. I created a static class with obvious routines EnableHandler()and DisableHandler(), as well as a handler function with behavior depending on the previous state: if an interrupt has already been requested, then just stop and return, otherwise set arg.Canceland set the interrupt request flag, Thus, when the benchmark starts , it allows the handler, and then checks the interrupt flag for each main loop; upon completion, it disables the handler and, if necessary, passes the interrupt request to the highest caller.

However, this approach works only once: after the handler was removed for the first time (regardless of when it was started or not), setting it again after that no longer has an effect - the operation does not cause errors, but the handler never Gets control when an event occurs . Is this the expected behavior in .NET event processing?

There are many topics related Console.CancelKeyPressto SO and other forums, but almost none of them are considering removing a handler, so it is not surprising that they did not encounter difficulties. However, in “ How to use ConsoleCancelEventHandler several times ” some similar (?) Problem was mentioned, but this application was a complicated GUI for several external console utilities that were launched on demand, and the problem was clearly related to an explicit exception that occurred when trying add a handler a second time - which is not my case.

, .NET, , .NET Visual Basic ( AddHandler RemoveHandler VB.NET += -= #). .NET 4.5 Visual Basic 2012 Windows 7 x86-64 .

DisableHandler(), : , , . , .

PS. Chris Dunaway:

' Usage example
Dim fAbort As Boolean = False
BreakHandler.Enable()
For Each oImplementation As Implementation In oCompetition.Implementations
    Benchmark(oImplementation)
    If BreakHandler.AbortRequested() Then fAbort = True : Exit For
Next
BreakHandler.Disable()
Return Not fAbort


Public Class BreakHandler

    Protected Shared AbortFlag As Boolean = False
    Protected Shared HandlerInstalled As Boolean = False
    Protected Shared HandlerEnabled As Boolean = False

    Public Shared ReadOnly Property AbortRequested() As Boolean
        Get
            If AbortFlag Then
                AbortFlag = False
                Return True
            Else
                Return False
            End If
        End Get
    End Property

    Public Shared Sub Enable()
        If HandlerEnabled Then Return
        If Not HandlerInstalled Then
            AddHandler Console.CancelKeyPress, AddressOf Handler
            HandlerInstalled = True
        End If
        HandlerEnabled = True
    End Sub

    Public Shared Sub Disable()
        AbortFlag = False
        If Not HandlerEnabled Then Return
        ' This is where the handler was removed originally.
        'RemoveHandler Console.CancelKeyPress, AddressOf Handler
        HandlerEnabled = False
    End Sub

    Protected Shared Sub Handler(ByVal sender As Object, ByVal args As ConsoleCancelEventArgs)
        If (Not HandlerEnabled) OrElse AbortFlag Then
            Return  ' Stand down, allow complete abortion.
        Else
            Console.Out.WriteLine("Will abort on next cycle. Press Break again to quit.")
            AbortFlag = True
            args.Cancel = True
        End If
    End Sub

End Class
+4
1

, . .NET Framework , 4.5.1. , , Windows , . , , . reset " ". , AddHandler, .

connect.microsoft.com, , , .

, . , . Main():

    AddHandler Console.CancelKeyPress, Sub(s, e)
                                       End Sub

, , . , , . CancelKeyPress , , . Release x86. , volatile, CPU, , VB.NET . , ManualResetEvent.

+5

Source: https://habr.com/ru/post/1533916/


All Articles