wpf TextBox复制文字卡顿 和迅雷的冲突

发布时间 2023-10-19 17:51:15作者: trykle

迅雷会在后台一直监控读取用户剪切板,如果发现是下载格式,将会弹出下载框

在wpf的TextBox中,快速按Ctrl C会导致获取剪切板和设置剪切板的命令争抢引发System.Runtime.InteropServices.COMException
这个异常

通过查看源代码,发现在复制文字时,他们都不同情况的重试,暂停
这可能就导致了一直ctrl + c,一直:失败、暂停、重试、卡顿

这个情况,仅测试在wpf会存在,其他的文本框,vs 浏览器 记事本等等都没有出现这种情况

在winform中
System.Windows.Forms
public sealed class Clipboard

 /// <include file='doc\Clipboard.uex' path='docs/doc[@for="Clipboard.SetDataObject2"]/*' />
        /// <devdoc>
        /// <para>Overload that uses default values for retryTimes and retryDelay.</para>
        /// </devdoc>
        public static void SetDataObject(object data, bool copy) {
            SetDataObject(data, copy, 10 /*retryTimes*/, 100 /*retryDelay*/);
        }

在wpf中
System.Windows
public static class Clipboard

internal static void CriticalSetDataObject(object data, bool copy)

...
 while (true)
            {
                // Clear the system clipboard by calling OleSetClipboard with null parameter.
                int hr = OleServicesContext.CurrentOleServicesContext.OleSetClipboard(dataObject);
 
                if (NativeMethods.Succeeded(hr))
                {
                    break;
                }
 
                if (--i == 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
 
                Thread.Sleep(OleRetryDelay);
            }
 
            if (copy)
            {
                // Dev10 bug 835751 - OleSetClipboard and OleFlushClipboard both modify the clipboard
                // and cause notifications to be sent to clipboard listeners. We sleep a bit here to
                // mitigate issues with clipboard listeners (like TS) corrupting the clipboard contents
                // as a result of these two calls being back to back.
                Thread.Sleep(OleFlushDelay);
 
                Flush();
            }