我得到一个关于使用不同线程的错误

本文关键字:于使用 线程 错误 一个 | 更新日期: 2023-09-27 18:19:25

当我点击ActionButton时,有一个计时器开始,3秒后,它必须触发一个方法来改变当前的ContentPage到另一个页面。但我得到一个消息:调用线程不能访问这个对象,因为不同的线程拥有它。我不明白我做错了什么。但是,如果我把ChangeContent()方法在click_event,它的工作,但在_tm_elapsed它不工作?

using smartHome2011.FramePages;
using System.Timers;
public partial class AuthenticationPage : UserControl
{
    private MainWindow _main;
    private Storyboard _storyboard;
    private Timer _tm = new Timer();
    private HomeScreen _homeScreen = new HomeScreen();
    public AuthenticationPage(MainWindow mainP)
    {
        this.InitializeComponent();
        _main = mainP;
    }
    private void ActionButton_Click(object sender, System.EventArgs eventArgs)
    {
        _main.TakePicture();
        identifyBox.Source = _main.source.Clone();
        scanningLabel.Visibility = Visibility.Visible;
        _storyboard = (Storyboard) FindResource("scanningSB");
        //_storyboard.Begin();
        Start();
    }
    private void Start()
    {
        _tm = new Timer(3000);
        _tm.Elapsed += new ElapsedEventHandler(_tm_Elapsed);
        _tm.Enabled = true;
    }
    private void _tm_Elapsed(object sender, ElapsedEventArgs e)
    {
        ((Timer) sender).Enabled = false;
        ChangeContent();
        //MessageBox.Show("ok");
    }
    private void ChangeContent()
    {
        _main.ContentPage.Children.Clear();
        _main.ContentPage.Children.Add(_homeScreen);
    }
}

我得到一个关于使用不同线程的错误

描述

你必须使用Invoke来确保UI线程(创建你的控件的线程)将执行它。

<标题> 1。如果你使用的是Windows窗体,那么就使用

示例

private void ChangeContent()
{
    if (this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(ChangeContent));
        return;
    }
    _main.ContentPage.Children.Clear();
    _main.ContentPage.Children.Add(_homeScreen);
}
<标题> 2。如果你正在使用WPF,那么就使用
private void _tm_Elapsed(object sender, ElapsedEventArgs e)
{
    ((Timer) sender).Enabled = false;
    this.Dispatcher.Invoke(new Action(ChangeContent), null);
    //MessageBox.Show("ok");
}

的更多信息

Windows窗体

    MSDN -控制。Invoke方法MSDN -控制。InvokeRequired地产
WPF

  • MSDN -分派器。Invoke方法
  • MSDN - Dispatcher类

TimerElapsed事件中执行的逻辑在与其他代码分开的线程上运行。这个线程不能访问主/GUI线程上的对象。

这个线程应该帮助你找到如何做到这一点:如何从c#中的另一个线程更新GUI ?

我怀疑你正在使用System.Threading.Timer。您可以通过使用Windows来避免跨线程操作。形式定时器:http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx该计时器使用常规消息,事件发生在UI的同一线程上。要使用的事件不再是"Elapsed",而是"Tick"阅读这里的文档:http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.tick.aspx