简体   繁体   English

退订然后订阅Console.CancelKeyPress

[英]unsubscribe then subscribe to Console.CancelKeyPress

I noticed that subscribing then unsubscribing from Console.CancelKeyPress makes the next subscription fail. 我注意到从Console.CancelKeyPress订阅然后取消订阅会使下一个订阅失败。

Even stranger: starting of with an empty eventhandler fixes this. 甚至陌生人:从一个空的事件处理程序开始即可解决此问题。

Could anybody explain this behavior? 有人可以解释这种行为吗?

    class Program
    {
        static void Main(string[] args)
        {
            Console.TreatControlCAsInput = false;
// 2:       uncomment following for an unexpected fix...
            //Console.CancelKeyPress += (s, a) => { };

            Console.CancelKeyPress += Handler_1;
            Console.WriteLine("Press Ctr+C to prove that Handler_1 cancels key press.");
            Console.ReadLine();

            Application.DoEvents(); // make sure events are handled before unsubscribe
            Console.CancelKeyPress -= Handler_1;

// 1:       uncomment following to prove failure...
            //Console.CancelKeyPress += Handler_2;
            //Console.WriteLine("Press Ctr+C to prove that Handler_2 cancels key press.");
            //Console.ReadLine();

            Application.DoEvents(); // make sure events are handled
            Console.WriteLine("End of demo, type something to prove application is still responsive.");
            Console.ReadLine();
        }

        private static void Handler_1(object sender, ConsoleCancelEventArgs args)
        {
            args.Cancel = true;
            Console.WriteLine("Key press is canceled by Handler_1");
        }

        private static void Handler_2(object sender, ConsoleCancelEventArgs args)
        {
            args.Cancel = true;
            Console.WriteLine("Key press is canceled by Handler_2");
        }
    }

It is a bug in the CancelKeyPress implementation 这是CancelKeyPress实现中的错误

public static event ConsoleCancelEventHandler CancelKeyPress {
                [System.Security.SecuritySafeCritical]  // auto-generated
                [ResourceExposure(ResourceScope.Process)]
                [ResourceConsumption(ResourceScope.Process)]
                add {
                    new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();

                    lock(InternalSyncObject) {
                        // Add this delegate to the pile.
                        _cancelCallbacks += value;

                        // If we haven't registered our control-C handler, do it.
                        if (_hooker == null) {
                            _hooker = new ControlCHooker();

// BUG: after you unsubscribe from CancelKeyPress it becomes null
// and when you subscribe to CancelKeyPress again the call below will never be called. In the Remove part they will not set _hooker to null.
                        _hooker.Hook();
                    }
                }
            }
            [System.Security.SecuritySafeCritical]  // auto-generated
            [ResourceExposure(ResourceScope.Process)]
            [ResourceConsumption(ResourceScope.Process)]
            remove {
                new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();

                lock(InternalSyncObject) {
                    // If count was 0, call SetConsoleCtrlEvent to remove cb.
                    _cancelCallbacks -= value;
                    Contract.Assert(_cancelCallbacks == null || _cancelCallbacks.GetInvocationList().Length > 0, "Teach Console::CancelKeyPress to handle a non-null but empty list of callbacks");
                    if (_hooker != null && _cancelCallbacks == null)
                        _hooker.Unhook();
//BUG: It Unhooks but does not set _hooker to null.
                    }
                }
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在.NET 4中使用Console.CancelKeyPress? (在.NET 3.5及更低版本中正常工作) - How do I use Console.CancelKeyPress in .NET 4? (Works fine in .NET 3.5 and below) 为什么在任务运行时添加 Console.CancelKeyPress 处理程序块调试器 CTRL+C 会退出 - Why does adding a Console.CancelKeyPress handler block debugger CTRL+C exit when a Task is running 在.NET控制台应用程序上使用CancelKeyPress事件 - Using CancelKeyPress event on a .NET console app WCF 回调服务订阅\\取消订阅 - WCF Callback service Subscribe\Unsubscribe 捕获CancelKeyPress以在安全点停止异步控制台应用程序 - Capturing CancelKeyPress to stop an async console app at a safe point 在解除CancelKeyPress事件之前,如何保持控制台处于打开状态? - How can I keep a console open until CancelKeyPress event is fired? 动态订阅/取消订阅事件 - Dynamically subscribe/unsubscribe from events 在 TPL 数据流中动态订阅/取消订阅 - Dynamically subscribe/unsubscribe in TPL Dataflow 订阅并在第一次操作后立即取消订阅 - Subscribe and immediately unsubscribe after first action SerialPort.DataReceived重复订阅/取消订阅 - SerialPort.DataReceived repeatedly subscribe/unsubscribe
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM