1

编辑#1:我已将 worker.RunWorkerAsync() 放在我的计时器循环中,并且我的应用程序不再关闭。虽然现在似乎什么都没有发生。

出于性能原因,我需要将 DispatcherTimers 替换为在不同线程中运行的其他计时器。有很多延迟/冻结,所以 DispatcherTimer 不再是一个选项。

我在实际更新我的 GUI 线程时遇到问题,我的应用程序似乎总是在没有任何警告/错误的情况下关闭。 我主要一直在尝试使用 BackGroundWorker 来解决我的问题。当我启动它时,一切都会导致我的应用程序关闭。

一些代码示例将非常受欢迎。

旧代码调度程序代码:

    public void InitializeDispatcherTimerWeging()
    {
        timerWegingen = new DispatcherTimer();
        timerWegingen.Tick += new EventHandler(timerWegingen_Tick);
        timerWegingen.Interval = new TimeSpan(0, 0, Convert.ToInt16(minKorteStilstand));
        timerWegingen.Start();
    }

    private void timerWegingen_Tick(object sender, EventArgs e)
    {
        DisplayWegingInfo();
        CaculateTimeBetweenWegingen();
    }

应每 5 秒调用一次 DisplayWegingInfo() 和 Calculate 方法。

GUI 更新发生在Calculate 方法中。有一个按钮被动态创建并添加到observerableCollection。

按钮创建(短版):

    public void CreateRegistrationButton()
    {
        InitializeDispatcherTimerStilstand();

        RegistrationButton btn = new RegistrationButton(GlobalObservableCol.regBtns.Count.ToString());
        btn.RegistrationCount = GlobalObservableCol.regBtnCount;
        btn.Title = "btnRegistration" + GlobalObservableCol.regBtnCount;
        btn.BeginStilstand = btn.Time;

        GlobalObservableCol.regBtns.Add(btn);
        GlobalObservableCol.regBtnCount++;

        btn.DuurStilstand = String.Format("{0:D2}:{1:D2}:{2:D2}", 0, 0, 0);         
    }

使用线程计时器的新代码在与 GUI 不同的线程中运行

    public void InitializeDispatcherTimerWeging()
    {
        worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
        worker.RunWorkerAsync();
    }

    void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        TimerCallback callback = MyTimerCallBack;
        timerWegingen = new Timer(callback);

        timerWegingen.Change(0, 5000);
    }


    private void MyTimerCallBack(object state)
    {
        DisplayWegingInfo();
        CaculateTimeBetweenWegingen();
    }

我的计时器在一个单独的线程中运行,然后是 GUI 线程(即 dispatcherTimer 使用的)。但我似乎无法将此更新发送到 UI 线程本身,因此更新实际上在 UI 中实现。

该按钮通过另一个计时器每 1 秒重新填充一次新值。“DuurStilstand”是一个依赖属性

    private void FillDuurStilstandRegistrationBtn()
    {
        TimeSpan tsSec = TimeSpan.FromSeconds(stopWatch.Elapsed.Seconds);
        TimeSpan tsMin = TimeSpan.FromMinutes(stopWatch.Elapsed.Minutes);
        TimeSpan tsHour = TimeSpan.FromMinutes(stopWatch.Elapsed.Hours);

        if (GlobalObservableCol.regBtns.Count >= 1
                    && GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].StopWatchActive == true)
        {
            GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].DuurStilstand =
                            String.Format("{0:D2}:{1:D2}:{2:D2}", tsHour.Hours, tsMin.Minutes, tsSec.Seconds);
        }
    }

我需要在上述方法中使用来自 Dispatcher 的调用吗?如果是这样,具体如何?

在初始化BackGroundWorker的doWork方法后不确定如何调用ui线程,我的应用程序在启动后一直关闭。我已经尝试在几种方法中使用 Dispatcher.BeginInvoke,但到目前为止都失败了。目前我不知道如何实现它。

上面所有的代码都写在一个单独的 c# 类中。

最好的问候,杰克兹

4

1 回答 1

1

当我运行我的代码示例时,DisplayWegingInfo() 试图访问 UI 组件时抛出异常。我们需要从 Timer 线程调用 Invoke() 来更新 UI。请参阅下面的 DisplayWegingInfo()。注意:这假设 CaculateTimeBetweenWegingen() 不与 UI 交互。

   void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        TimerCallback callback = MyTimerCallBack;
        timerWegingen = new System.Threading.Timer(callback);
        timerWegingen.Change(0, 3000);

    }

    private void MyTimerCallBack(object state)
    {
        DisplayWegingInfo();
        CaculateTimeBetweenWegingen();
    }

    private void DisplayWegingInfo()
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new Action(DisplayWegingInfo));
            return;
        }

        // at this point, we are on the UI thread, and can update the GUI elements
        this.label1.Text = DateTime.Now.ToString();
    }

    private void CaculateTimeBetweenWegingen()
    {
        Thread.Sleep(1000);
    }
于 2012-04-17T13:41:42.183 回答