4

我正在使用计时器作为

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

接下来,我将其间隔更改为

clipboardTimer.Change(1000, 30000);

在句柄超时功能中,即ClearClipboard我想将剪贴板清除为

void ClearClipboard(object o)
{
    Clipboard.SetText("");
}

但也有System.Unauthorised例外。也许,这是因为有两个不同的线程。那么,我怎样才能有效地调用清除剪贴板呢?

4

3 回答 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代替Timer。该DispatcherTimer事件确实在 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("");
}
于 2013-06-13T06:26:44.953 回答
1

要求在 UI 线程Dispatcher上运行Clipboard.SetText("");,因为计时器的超时事件是在非 UI 线程上引发的,并且您不能从另一个线程更改由 UI 线程创建的控件

尝试这样的事情

void ClearClipboard(object o)
{
   Dispatcher.Invoke( () => { Clipboard.SetText(""); });
}
于 2013-06-13T05:44:46.670 回答
1

您将需要InvokeGUI 线程上的方法。你可以通过调用来做到这一点Control.Invoke

 control.Invoke(new Action(() => control.Text = "new text")));
于 2013-06-13T05:49:04.050 回答