当计时器超时时清空剪贴板

4

我正在使用计时器作为

System.Threading.Timer clipboardTimer = new Timer(ClearClipboard);

接下来,我将它的时间间隔更改为

clipboardTimer.Change(1000, 30000);

在超时处理函数中,即ClearClipboard,我希望能够清除剪贴板。
void ClearClipboard(object o)
{
    Clipboard.SetText("");
}

但是出现了 System.Unauthorised 异常。可能是因为有两个不同的线程。那么,如何高效地调用清除剪贴板?

3个回答

3
此错误是因为 Timer 事件在与UI线程不同的线程上触发。您可以通过两种方式之一更改UI元素。第一种方法是告诉 Dispatcher 对象在UI线程上执行代码。如果具有 Timer 的对象是 DependencyObject (例如 PhoneApplicationPage ),则可以使用 Dispatcher 属性。这可以通过 BeginInvoke 方法完成。
void ClearClipboard(object o)
{
    Dispatcher.BeginInvoke(() => Clipboard.SetText(""));
}

如果你的对象不是一个DependencyObject,你可以使用Deployment对象访问Dispatcher

void ClearClipboard(object o)
{
    Deployment.Current.Dispatcher.BeginInvoke(() => Clipboard.SetText(""));
}

第二种选择是使用 DispatcherTimer 替代 TimerDispatcherTimer 事件在 UI 线程上触发!
// Create the timer
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(3);
timer.Tick += TimerOnTick;

// The subscription method
private void TimerOnTick(object sender, EventArgs eventArgs)
{
    Clipboard.SetText("");
}

谢谢 @Shawn Kendrot,我已经使用了DispatcherTimer,它运行得很好。 - Jatin

1
要求 Dispatcher 在 UI 线程上运行 Clipboard.SetText("");,因为定时器的超时事件是在非 UI 线程上引发的,您不能从另一个线程更改由 UI 线程创建的控件。尝试像这样做。
void ClearClipboard(object o)
{
   Dispatcher.Invoke( () => { Clipboard.SetText(""); });
}

1

您需要在 GUI 线程上调用该方法。您可以通过调用 Control.Invoke 来实现:

 control.Invoke(new Action(() => control.Text = "new text")));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接