I've got the same issue and googled a lot but found no workable solutions. The timeout solution is not applicable to my situation. At last it seems the only way that really works is to use a global hook. 
For more information about hook, please refer to this excellent post: Global keyboard capture in C# application 
So, in the hook handling code taken from above link, add something like this:
    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            if (vkCode == 121)  //F10 key
            {
                try
                {
                    UnhookWindowsHookEx(_hookID);//avoid ESC key to be captured
                    SetForegroundWindow(_handle);
                    SendKeys.Send("{ESC}");
                    _hookID = SetHook(_proc);
                }
                catch (Exception ex)
                {
                }
            }
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }
related code below:
    using System.Windows.Automation; //you need to reference UIAutomationClient and UIAutomationTypes
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    private IntPtr _handle;
    //I forget where I got the code of the function below, probably also from stackoverflow. Thanks to the original author!
    private IntPtr getIntPtrHandle(IWebDriver driver, int timeoutSeconds = 30)
    {
        var end = DateTime.Now.AddSeconds(timeoutSeconds);
        while (DateTime.Now < end)
        {
            // Searching by AutomationElement is a bit faster (can filter by children only)
            var ele = AutomationElement.RootElement;
            foreach (AutomationElement child in ele.FindAll(TreeScope.Children, Condition.TrueCondition))
            {
                if (!child.Current.Name.Contains(driver.Title)) continue;
                return new IntPtr(child.Current.NativeWindowHandle); ;
            }
        }
        return IntPtr.Zero;
    }
also put _handle = getIntPtrHandle(webdriver); somewhere BEFORE your webdriver.Navigate().GoToUrl() statement.
I tested the above. After excecuting GoToUrl, press F10 somewhere (sometimes twice) and the page stops loading.