C# Progressbar的行为很奇怪

C# Progressbar的行为很奇怪,c#,winforms,multithreading,progress-bar,C#,Winforms,Multithreading,Progress Bar,我刚刚在C#中创建了一个应用程序,它使用一个线程轮询UART接收事件。 如果接收到数据,则会在我的主线程(GUI)中触发一个事件,并通过PerformStep()方法控制进度条(当然,我之前也相应地设置了最大值)。 使用以下表达式调用PerformStep以处理跨线程 this.Invoke((Action)delegate{progressBar2.PerformStep();}) 运行此应用程序时,progressbar从未达到其最终值。它停止在80%。当调试并停在上面提到的线路上时,使用

我刚刚在C#中创建了一个应用程序,它使用一个线程轮询UART接收事件。 如果接收到数据,则会在我的主线程(GUI)中触发一个事件,并通过PerformStep()方法控制进度条(当然,我之前也相应地设置了最大值)。 使用以下表达式调用PerformStep以处理跨线程

this.Invoke((Action)delegate{progressBar2.PerformStep();})
运行此应用程序时,progressbar从未达到其最终值。它停止在80%。当调试并停在上面提到的线路上时,使用单个步骤,一切都可以正常工作。我不知道发生了什么事

在主线程上启动读取线程:

pThreadWrite = new Thread(new ThreadStart(ReadThread));
pThreadWrite.Start();
读线程:

private void ReadThread()
{
while(1)
{
    if (ReceiveEvent)
    {       
    FlashProgressBar();
    }
}
}
在主线程中触发的事件:

private void FlashProgressBar()
{
this.Invoke((Action)delegate { progressBar2.PerformStep();});
} 
(这是我代码的简化表示)

似乎内部进程比视觉进程快

编辑2: 好吧,我想我明白了。问题在于处理跨线程的invoke方法。我发现这句话是这样写的:

不,它是任何UI的基础,至少在Windows中是如此。Windows窗体中的消息架构不是什么新的东西,甚至是C++应用程序在Windows中工作的方式也是一样。如果您试图更新进度条或其他不应跨线程调用的内容。相反,对进度变量使用互锁写入,UI线程每隔一定时间读取该变量

是的,可以有任意长的延迟。Invoke通过向目标控件发送Windows消息来工作,因此只有在目标线程发送消息时才会对其进行处理。如果线程已经在处理一条消息,并且该处理需要时间,那么在线程泵送下一条消息并因此处理调用之前,可能会有相当大的延迟

所以我需要找到另一种解决方案,比如等待BeginInvoke方法完成

编辑:

如果我插入一些thread.sleep()语句,它似乎可以工作。可能是使用的计时器有问题。此计时器由读取线程启动,如果超过此时间,则触发事件:

读线程:

 private void ReadThread()
    {
        FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
        UInt32 numBytesAvailable = 0;         

        while (true)
        {
            ftStatus = myFtdiDevice.GetRxBytesAvailable(ref numBytesAvailable);
            if (ftStatus == FTDI.FT_STATUS.FT_OK)
            {
                 // read data and start timer                    
                 TimeoutWaitForAckn.Start();
            }
        }
    }
然后,如果计时器超过,则触发事件。睡眠宣言明确指出:

    private void Timeout_Handler(object sender, System.Timers.ElapsedEventArgs e)
    {
        Thread.Sleep(300);
        Trigger_ReportBufferReceivedEvent(ReceiveBuffer);
    }

考虑到线程、计时器和事件,是否存在任何已知问题?使用System.Timers.Timer。

我认为我们无法在不了解应用程序其余部分的情况下编译或运行一段代码来帮助您

我试图重现你所描述的问题,但恐怕没有发生。我有(它实际上与您的代码相同)。代码显示了一个带有进度条和按钮的表单。单击按钮,进度条将在10秒内一直上升到100%。一旦到达末尾,就会触发
Debugger.Break()


如果您可以将上述代码更改为实际再现您的问题的代码,并将其作为一个独立的示例发布,那么我们将能够帮助您。

WinForms、WPF或SilverLight或其他什么?(如果WinForms)您是否考虑过这样一个事实:
PerformStep
预付了
ProgressBar
Step
属性给出的金额,并且该属性默认为
10
而不是
1
?我认为代码本身太复杂,太多,无法在这里发布,所以我试着提取相关的片段。但是,如果您的示例运行良好,那么软件的另一部分可能会出现问题。。。