关于C# WPF中的DoEvents,要稳定且快速的,哪位有比较完美的解法?

wShineboy 2018-06-07 04:31:21
RT:使用C#时,相信各位童鞋在WinFrom中没少用Application.DoEvents(如同VB6的DoEvents)。但到了WPF中,这个东西就莫名其妙的被MS忽略了。

在长时间循环处理中,进程阻塞实在难免,网上也有不少DoEvents的解法,效果可以达到,但不是不稳定就是影响速度。下面这一串程序可能比较普及,可惜它不是很稳定,有时会导致窗体停止响应。
        private static DispatcherOperationCallback exitFrameCallback = new DispatcherOperationCallback(ExitFrame);

/// <summary>
/// Processes all UI messages currently in the message queue.
/// </summary>
public static void DoEvents()
{
DispatcherFrame nestedFrame = new DispatcherFrame();
DispatcherOperation exitOperation = Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, exitFrameCallback, nestedFrame);
Dispatcher.PushFrame(nestedFrame);
if (exitOperation.Status != DispatcherOperationStatus.Completed)
{
exitOperation.Abort();
}
}

private static Object ExitFrame(Object state)
{
DispatcherFrame frame = state as DispatcherFrame;
// Exit the nested message loop.
frame.Continue = false;
return null;
}


后来俺找了个老外写的东西,也能达到类似效果,不过好像有点拖速度——俺的程序需要实时同步单片机的数据,时间很宝贵。
就是这个——
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new System.Threading.ThreadStart(delegate { }));
...全文
2414 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
guojun0718 2020-07-04
  • 打赏
  • 举报
回复
想想一下,示波器怎么实时显示曲线?1K算个屁。示波器都上G了。
zslefour 2019-09-11
  • 打赏
  • 举报
回复
对于一个业余的编程爱好者来说,还未接触过异步,年过半百的我,现在开始去了解下异步看看。
编程有钱人了 2018-06-13
  • 打赏
  • 举报
回复
异步,异步,异步重要的事情说三遍,等你用熟练了,你会发现这个东西真好
  • 打赏
  • 举报
回复
纠结”1KHz“的前提是整个系统是同步、卡死主线程式的编程。比如说我的机器当前 windows 下有2000个线程,假设你应要只有20个线程做所有的事情,你认为这样就能保证每一个线程的”严格的时间顺序“,那么其实你就不适合使用说面 windows 这类操作系统,你应该使用比较原始的、专门为工控机开发的操作系统啊!!!!
  • 打赏
  • 举报
回复
比如说你在一个 Mouse_Move 事件处理过程中调试,刚处理2行代码,突然掉入了 Key_Down 事件处理过程中,然后突然又调入了定时器事件处理过程中,然后又跳回 Mouse_Move 事件过程,然后发现又处理了下一个 Mouse_Move 事件,然后又发现又跳回了第一个 Mouse_Move 事件处理阶段(因为 DoEvents 的原因,第一个事件处理还没有完毕,就混乱地迭代无数其它的事件过程中,然后有跳回)。 ”稳定且快速“这可能是指单线程编程习惯下的编程。但是单线程下,你就更加不应该考虑什么 DoEvents。单线程下要做到”稳定“你就更得保证事件处理过程是按照严格的顺序执行的,千万不能递归迭代胡乱——随机——从中间事件处理过程中去陷入其它事件处理过程,否则程序就根本不是预期的可调式的结果。除非你的程序非常小非常简单才用DoEvents。
  • 打赏
  • 举报
回复
以消息的调用轮询方式为代价的 DoEvents——不支持异步处理时——它不仅仅是一般地处理了消息,而是把消息的正常地顺序控制逻辑给混乱成为了高度嵌套递归的逻辑。比如说事件A、B、C、D.......原本是顺序触发的,当你在 A 中写了一个 DoEvents,A事件响应过程中递归嵌入了B、C、D.....的处理逻辑,特别是有的人甚至还喜欢在一个 while 循环中去使用 DoEvents 那么就更惨了,事件完全可能递归爆发(当你的代码会触发事件发生时)、并且次序混乱(在主线程完全诡异地前后颠倒几十个事件次序)、内存使用暴增、主线程卡死。
蒋晟 2018-06-12
  • 打赏
  • 举报
回复
DoEvents本身是启动另一个消息循环,不做异步的话,只能改善界面的更新,但是是以拖慢程序为代价的,因为插入了消息循环的代码。 多核计算机上,每个线程顶多能占一个核,要充分发挥机器性能,必须做异步。
xuzuning 2018-06-12
  • 打赏
  • 举报
回复
相信你的机器的上网速度都是每秒数兆了,(再差的套餐也是几百K)。为何要纠结 1KHz 能否保证速度呢? 不行的是你,而不是机器
wShineboy 2018-06-12
  • 打赏
  • 举报
回复
MCU启动后,它采AD的速度可以达到1KHz以上,发到上位机的数据美妙只有一两百帧,即使实时循环也可能来不及接收。异步能保证速度吗?
  • 打赏
  • 举报
回复
引用 楼主 wShineboy 的回复:
在长时间循环处理中,进程阻塞实在难免,
有事件就处理事件,没事件还循环什么?这完全说明了你不是事件驱动的设计,而是死循环去轮询的习惯。 事件处理过程中,为了不阻塞 UI 线程,那么就应该采用异步方式来处理。假设事件本来就发生在 I/O 或者子 Work 线程,而不是 UI 线程,那么它本身也就不可能卡死 UI 刷新。在异步子线程中,要访问 UI 控件就得使用 control.BeginInvoke 方式,从这类代码“有没有”就能看到你设计的出发点是什么样的。
  • 打赏
  • 举报
回复
现在的 .net 编程知识,可能把 Task 作为一个核心能力来看待,例如
var data = await ReceiveDatas(.....);
去UI显示(data);
这类省得写 BeginInvoke 的代码也很常见了。这里的关键就在于 await 机制,根本不是阻塞的,而是异步的。这样当异步回调而获得 data 之后,又去主线程进行显示 data 操作了。 关键就在于异步知识。不是死守着同步、阻塞思路去“设计解法”。
  • 打赏
  • 举报
回复
引用 楼主 wShineboy 的回复:
RT:使用C#时,相信各位童鞋在WinFrom中没少用Application.DoEvents(如同VB6的DoEvents)。但到了WPF中,这个东西就莫名其妙的被MS忽略了。
VB(不是 vb.net)根本不支持异步多线程,所以它使用 Application.DoEvents 方法来打乱 windows 消息泵的响应次序(使得一个 UI 消息处理过程中强行执行后边的消息)。这本来是 VB 的糟粕,是不得已才这样写程序的。 到了 .net 时代,程序员要学会异步、多线程去编程,并且在子线程需要访问 UI 控件时使用 control.BeginInvoke/Invoke 委托方式。这才是合适的并且不打乱 windows 消息次序的做法。
cheng2005 2018-06-08
  • 打赏
  • 举报
回复
除了把数据显示到界面上这一步,你的所有逻辑都和UI无关,为什么要放到主线程里?还要用DoEvents()... 另外,“每秒200帧数据”不是说你每秒要刷新200次UI,你又不是超人眼,一点意义都没有。24帧的电影你看的还不够流畅? 好好规划你的逻辑,而不是用什么奇技淫巧来做一个大玩具。
wShineboy 2018-06-08
  • 打赏
  • 举报
回复
哈,打字太快了——应该是循环处理阻塞了UI,导致界面假死。 大家看看这样的流程,能不能启一个辅助线程来跑。 给下位机发命令让它开始工作,其工作过程中以1KHz的速度采样,每秒发200帧数据到PC。上位机软件须即时显示其采样数据并绘制曲线,直到单片机完成工作流程。 即:下位机成功收到命令后开始工作,以“停止发送AD”这样的方式告诉上位机工作完成。
while (true)
            {
                while(SerialPort.BytesToRead <XXX)
                {
                    //串口可读取数据不足则等待,等待超时则认为工作流程结束,结束时return
                }
                DoEvents();

                //接收AD,经转换后显示数值并绘制实时曲线
                //刷新曲线和数据,每秒三次即可保证连贯性,刷新后须 DoEvents
                //……………其它处理…………………………………
            }
圣殿骑士18 2018-06-07
  • 打赏
  • 举报
回复
偷懒才用Application.DoEvents
  • 打赏
  • 举报
回复
进程怎么能阻塞,进程表示操作系统为运行PE32文件(PE32+)而分配一个虚拟地址空间,用它来确保程序之间的运行互不影响,提供一个界定的区域。
Invoke 使用线程同步执行第二个参数中的逻辑,导致UI显示更新不及时。 同步单片机数据 并不一定非得要接受一次就必须处理一次,可以加入到队列集合中,然后去依次处理队列集合中的数据。
cheng2005 2018-06-07
  • 打赏
  • 举报
回复
除非做一些和UI相关的特殊功能(非常个性化的需求),不然应该用不到Application.DoEvents。
内容概要:本文研究了基于Q-Learning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制的应用,旨在提升其在复杂海洋环境下的控制性能。通过建立AUV的动力学模型,将Q-Learning算法与传统PID控制相结合,实现控制器参数的在线自适应优化,有效增强了系统的响应速度、稳定性和抗干扰能力。研究采用Matlab进行仿真验证,结果表明该方法在轨迹跟踪与姿态控制方面具有优越表现,为水下机器人智能控制提供了可行的技术路径与理论支持。; 适合人群:具备自动控制理论、强化学习或水下机器人建模背景,从事相关科研工作的研究人员、高校研究生及工程技术开发者。; 使用场景及目标:①应用于高精度、强鲁棒性的水下机器人运动控制系统设计;②开展智能PID控制器在非线性、时变系统的参数自整定研究;③作为强化学习在复杂工业控制场景落地的典型案例参考,推动算法与工程实践融合。; 阅读建议:建议结合提供的Matlab代码进行仿真实验,重点剖析Q-Learning与PID融合的架构设计、奖励函数设定及参数收敛过程,可进一步拓展至与其他智能优化算法(如DQN、Actor-Critic)的对比研究,深化对自适应控制机制的理解。
已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 Matlab 被视为一种功能卓越的编程平台,特别是在数值运算和数据分析方面展现出广泛的应用价值。在应对多元非线性回归的挑战时,Matlab 拥备多种工具和函数,支持用户对复杂的数据进行构建模型和适配。本指南将重点阐释在 Matlab 环境下如何执行多元非线性回归分析。 我们需要掌握三种关键的回归指令: 1. `polyfit(x,y,n)`:此函数适用于拟合一元幂函数,能够导出一个多项式模型。例如,若知晓数据呈现二次函数形态,可选择`n=2`来适配一个二次曲线。 2. `regress(y,x)`:这是一个多元线性回归指令,能够处理多个自变量对因变量的影响。即便数据并非完全呈现线性特征,该函数也能提供一个线性近似。 3. `nlinfit(x,y,’fun’,beta0)`:这是最为通用的非线性回归指令,适用于适配任何类型的函数,无论是一元或多元,前提是用户能够定义函数形式(`fun`参数)。 回归分析的核心在于寻找一组最优的系数,使得模型能够最恰当地描述数据。这通常涉及选择一个合适的函数形态,随后通过最小化误差平方和来估算系数。在Matlab,`regress`指令主要用于处理线性模型,而`nlinfit`则处理更为复杂的非线性模型。 对于多元线性回归模型,我们可以用如下形式进行表述: \[ y = \beta_0 + \beta_1x_1 + \beta_2x_2 + \cdots + \beta_px_p + \epsilon \] 其,\( y \)是因变量,\( x_1, x_2, \ldots, x_p \)是自变量,\( \beta_0, \beta_1, ...
内容概要:本文系统阐述了基于BP神经网络的语音特征信号分类方法,并提供了完整的Matlab代码实现。研究围绕语音信号的数据预处理、特征提取、神经网络结构设计、模型训练与分类测试等核心环节展开,详细展示了BP神经网络在语音识别任务的应用流程。通过构建多层前馈网络模型,利用误差反向传播算法优化权重,实现了对不同语音类别特征的高效分类,具有较强的工程实践价值和技术可复现性。; 适合人群:具备信号处理与机器学习基础知识,熟悉Matlab编程语言,从事语音识别、模式识别、人工智能等相关领域研究的学生及科研人员;特别适用于开展课程设计、毕业设计或科研项目的初级与级研究人员。; 使用场景及目标:①深入理解BP神经网络的基本原理及其在语音信号分类的具体实现过程;②掌握Matlab环境下语音信号特征提取与分类模型构建的全流程技术;③为语音识别、人机交互、智能听觉系统等实际应用场景提供可靠的算法基础与代码参考。; 阅读建议:建议读者结合所提供的Matlab代码逐行分析其实现逻辑,重点关注数据输入格式、网络参数初始化、训练迭代过程及分类性能评估;可通过调整隐含层节点数、学习率、激活函数等超参数,观察模型收敛性与分类准确率的变化,从而深化对神经网络调参策略的理解。

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧