【问题标题】:C# Form real time counter not woringC#表单实时计数器不起作用
【发布时间】:2021-10-23 15:13:51
【问题描述】:

我想在我控制的应用程序中的文本框中显示我打开和关闭阀门的次数,但我只能看到过程完成后的结果,我无法实时看到。

        private void button6_Click(object sender, EventArgs e) 
    {
        sayacValue = 0;
        int LoopCount = Convert.ToInt32(textBox_send.Text);
        
        for (int s = 0; s < LoopCount; s++)
        {
        OpenValf();
        IncreaseValfValue();
        System.Threading.Thread.Sleep(400);
        CloseValf();
        System.Threading.Thread.Sleep(400);
        }

    }

    

 public int IncreaseValfValue() //Counter Control Function
    {
        sayacValue++;
        sayac.Text = sayacValue.ToString();
        return sayacValue;
    }

我怎样才能使用 Thread 或任何其他方法来做到这一点?

【问题讨论】:

  • 为什么你认为当你阻塞 main(UI) 线程时 UI 会有一些变化? ...随意在async方法中使用await Task.Delay...
  • 除了 Selvin 所说的: 1. 不要相信用户输入。如果textbox_send 不包含有效整数,则会崩溃。 2. 根据我的经验,在处理硬件(您似乎正在处理)时,您不要假设您的请求已被执行,这一点至关重要。我总是有一个“1.检查值,2.发送新值,3.检查新值是否已传播到设备(=再次读取)”的系统。另请注意,WinForms 本质上不是“实时”(在计算机科学的定义中)。
  • 作为一个最小的改变,为什么不在sayac.Text = sayacValue.ToString() 之后调用sayac.Refresh() ;?
  • @kunif 它可以工作,但在 1 之后它说 3-5-7
  • 也许你正在其他地方做sayacValue++;,或者IncreaseValfValue();被调用了两次。

标签: c# .net multithreading winforms serial-port


【解决方案1】:

您应该使用 Microsoft 的响应式框架(又名 Rx) - NuGet System.Reactive.Windows.Forms - 然后您可以这样做:

using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reactive.Linq;
using System.Reactive.Disposables;

namespace WindowsFormsApp
{
    public partial class ExampleForm : Form
    {
        public ExampleForm()
        {
            InitializeComponent();
        }

        private SerialDisposable _subscription = new SerialDisposable();

        private void button6_Click(object sender, EventArgs e)
        {
            if (int.TryParse(textBox_send.Text, out int LoopCount))
            {
                if (LoopCount > 0)
                {
                    _subscription.Disposable =
                        Observable
                            .Interval(TimeSpan.FromMilliseconds(400.0))
                            .Take(LoopCount + 1)
                            .ObserveOn(this)
                            .Subscribe(
                                x => sayac.Text = $"{x}",
                                () => sayac.Text = "Done.");
                }

            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    相关资源
    最近更新 更多