如何实现按下按钮从while死循环中跳出

zhu5152 2017-07-04 05:28:03
程序是运行在手持机设备上的,现在程序中某一操作如果不成功,会一直执行改操作,直到成功或者按一个键退出。我现在写了个while循环通过返回值判断是否成功,不成功再次执行直到成功
do
{
sRet = WriteWalletInfo(ref CardBurseInfo, nCurCard, iWalletNum, dMonDeal, "11", out sErrText);

if (!sRet)
{
lb_Msg.Text = "写卡失败,请重试!";
}
}
while (!sRet);


现在还要加一个按键退出这个步骤,但是while死循环的时候按键没反应啊
...全文
2522 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
小灰狼 2017-07-06
  • 打赏
  • 举报
回复 1
1、后台执行的操作应该放在一个线程里进行,否则会把主界面的操作卡死,用户点界面没有响应 2、用一个变量控制是否有键按下 A simple demo, compile it as console application:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace TestWaitNotify {
	public partial class Form1 : Form {

		private Thread thread = null;
		private bool running = false;
		
		public Form1() {
			InitializeComponent();
		}

		private void execute() {
			running = true;
			int i = 0;
			while (running) {
				Console.WriteLine("执行操作 " + ++i + " ……");
			}
			Console.WriteLine("完成 ……");
			thread = null;
		}

		private void btnStart_Click(object sender, EventArgs e) {
			if (thread == null) {
				thread = new Thread(new ThreadStart(this.execute));
				thread.Start();
			}
		}

		private void btnStop_Click(object sender, EventArgs e) {
			running = false;
		}
	}
}
  • 打赏
  • 举报
回复
举个例子,比如说连续向卡片中写10遍数据还出错,你何必要写第11、20遍、1千遍、10万遍?为什么要无休止地继续写下去?假设连续3次写失败,你为什么不延迟100毫秒再写?假设连续6次写失败,你为什么不延迟1000毫秒再写? 还有很多类似的基本设计知识和经验。 如果认为用户能有多高配置的硬件就要尽量要多高配置的硬件,设计理念不注意去发挥硬件能力,那种不会监听、事件驱动设计,而以(子线程)死循环来模拟类似功能的做法是非常害人的。
  • 打赏
  • 举报
回复
进一步说,所谓的“某一个操作一直不成功,会一直重试”,这往往是哄小孩儿玩儿的程序。一旦用到实际的系统中,这种看似挺有理的东西,其实就是软件和系统性能的杀手,就是一锅鲜汤中混进了老鼠屎。 这类设计,首先要仔细考虑如何避免滥用CPU 时间的问题,如何尽可能少地做无用功的问题。如果不能避免无用功,有什么用?
  • 打赏
  • 举报
回复
引用 3 楼 zhu5152 的回复:
[quote=引用 1 楼 u010717459 的回复:] 加个bool变量 while(!exit && !sRet) 按键时更改状态 exit=true
这不是重点,重点是在执行while的时候,你按键是不会起作用的,要等while结束后才会执行按键事件[/quote] 重点是你既然在主线程死循环,然后又纠结在死循环的时候要响应按键事件,这是自相矛盾的。
加油馒头 2017-07-06
  • 打赏
  • 举报
回复
楼上思路是对的 卡死是因为在主线程,阻塞了
bloodish 2017-07-05
  • 打赏
  • 举报
回复
引用 9 楼 only_endure 的回复:
while循环在新线程里执行。在程序里建个AutoManualReset,置初始值为false. 在按钮的click里设置AutoManualReset.set
这是我喜欢的方式 不想界面假死,那么 1.不要放UI线程 2.while里加个Sleep(0),放出CPU时间片
正怒月神 2017-07-05
  • 打赏
  • 举报
回复
引用 10 楼 zhu5152 的回复:
能不能说得详细点
http://blog.csdn.net/jimlong/article/details/7653355
IEEE_China 2017-07-05
  • 打赏
  • 举报
回复
嗯,timer好, 给timer设个频率,比如:timer1.Interval = 200; 再加个事件,把while循环的内容写到timer1_Tick事件里。 其他按钮控制timer。
zhu5152 2017-07-05
  • 打赏
  • 举报
回复
引用 8 楼 hanjun0612 的回复:
看起来类似于扫描枪。 [quote=引用 4 楼 closurer 的回复:] while 阻塞了界面线程。
对啊,while明显阻塞了界面的主线程。 用timer。控制他的enable就可以了[/quote] 能不能说得详细点
一品梅 2017-07-05
  • 打赏
  • 举报
回复
while循环在新线程里执行。在程序里建个AutoManualReset,置初始值为false. 在按钮的click里设置AutoManualReset.set
正怒月神 2017-07-05
  • 打赏
  • 举报
回复
看起来类似于扫描枪。
引用 4 楼 closurer 的回复:
while 阻塞了界面线程。
对啊,while明显阻塞了界面的主线程。 用timer。控制他的enable就可以了
zhu5152 2017-07-05
  • 打赏
  • 举报
回复
引用 5 楼 From_TaiWan 的回复:
要在循环体内加一个按键接收,假设程序运行在控制台下,按下y继续循环 char isContinue='y'; do { sRet = WriteWalletInfo(ref CardBurseInfo, nCurCard, iWalletNum, dMonDeal, "11", out sErrText); if (!sRet) { lb_Msg.Text = "写卡失败,请重试!"; } isContinue=(char)Console.Read(); } while (!sRet && isContinue=='y');
那如果是通过钩子程序获取的键盘信息呢~~while的时候按键就不会有反应了吧?
zhu5152 2017-07-05
  • 打赏
  • 举报
回复
[quote=引用 5 楼 From_TaiWan 的回复:] 要在循环体内加一个按键接收,假设程序运行在控制台下,按下y继续循环 char isContinue='y'; do { sRet = WriteWalletInfo(ref CardBurseInfo, nCurCard, iWalletNum, dMonDeal, "11", out sErrText); if (!sRet) { lb_Msg.Text = "写卡失败,请重试!"; } isContinue=(char)Console.Read(); } while (!sRet && isContinue=='y'); [/quote] 那如果是通过钩子程序获取的键盘信息呢~~while的时候按键就不会有反应了吧?
crystal_lz 2017-07-05
  • 打赏
  • 举报
回复
引用 15 楼 bloodish 的回复:
sleep(0)有不妥吗? According to MSDN's documentation for Sleep: A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution. The important thing to realize is that yes, this gives other threads a chance to run, but if there are none ready to run, then your thread continues -- leaving the CPU usage at 100% since something will always be running. If your while loop is just spinning while waiting for some condition, you might want to consider using a synchronization primitive like an event to sleep until the condition is satisfied or sleep for a small amount of time to prevent maxing out the CPU.
斯国一
bloodish 2017-07-05
  • 打赏
  • 举报
回复
引用 14 楼 crystal_lz 的回复:
[quote=引用 13 楼 bloodish 的回复:] [quote=引用 9 楼 only_endure 的回复:] while循环在新线程里执行。在程序里建个AutoManualReset,置初始值为false. 在按钮的click里设置AutoManualReset.set
这是我喜欢的方式 不想界面假死,那么 1.不要放UI线程 2.while里加个Sleep(0),放出CPU时间片[/quote] Sleep(0)[/quote] sleep(0)有不妥吗? According to MSDN's documentation for Sleep: A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution. The important thing to realize is that yes, this gives other threads a chance to run, but if there are none ready to run, then your thread continues -- leaving the CPU usage at 100% since something will always be running. If your while loop is just spinning while waiting for some condition, you might want to consider using a synchronization primitive like an event to sleep until the condition is satisfied or sleep for a small amount of time to prevent maxing out the CPU.
crystal_lz 2017-07-05
  • 打赏
  • 举报
回复
引用 13 楼 bloodish 的回复:
[quote=引用 9 楼 only_endure 的回复:] while循环在新线程里执行。在程序里建个AutoManualReset,置初始值为false. 在按钮的click里设置AutoManualReset.set
这是我喜欢的方式 不想界面假死,那么 1.不要放UI线程 2.while里加个Sleep(0),放出CPU时间片[/quote] Sleep(0)
秋的红果实 2017-07-04
  • 打赏
  • 举报
回复
要在循环体内加一个按键接收,假设程序运行在控制台下,按下y继续循环 char isContinue='y'; do { sRet = WriteWalletInfo(ref CardBurseInfo, nCurCard, iWalletNum, dMonDeal, "11", out sErrText); if (!sRet) { lb_Msg.Text = "写卡失败,请重试!"; } isContinue=(char)Console.Read(); } while (!sRet && isContinue=='y');
闭包客 2017-07-04
  • 打赏
  • 举报
回复
while 阻塞了界面线程。
zhu5152 2017-07-04
  • 打赏
  • 举报
回复
引用 1 楼 u010717459 的回复:
加个bool变量 while(!exit && !sRet) 按键时更改状态 exit=true
这不是重点,重点是在执行while的时候,你按键是不会起作用的,要等while结束后才会执行按键事件
巴士上的邂逅 2017-07-04
  • 打赏
  • 举报
回复
这段代码要放在新线程里
加载更多回复(1)

110,533

社区成员

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

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

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