C# 编写 接收数据程序 的问题(高分回答满意可以再给100)
我编写了个程序,用能从单片机接收字符串,然后再显示出来。(省略一千字)这里简化说一下过程与问题:第一步,做的是按钮触发事件,点击一下,textbox1显示“123”,很简...
我编写了个程序,用能从单片机接收字符串,然后再显示出来。(省略一千字)
这里简化说一下过程与问题:
第一步,做的是按钮触发事件,点击一下,textbox1显示“123”,很简单。
然后,我开始做循环的,即点击一次,循环显示该字符串,我直接在按钮事件下写
while(true){textbox1.Text="123"}的死循环。果真是死循环。。。UI直接无响应。。。上网查询,说是另开线程可以解决死机问题,经历了无数尝试,我终于成功了线程加委托,代码如下:
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(DoWork));
thread.Start();
}
public delegate void MyInvokea();
public void DoWork()
{
MyInvokea mi = new MyInvokea(UpdateForm);
this.BeginInvoke(mi, new Object[] { });
}
public void UpdateForm()
{
this.textBox1.Text = "123";
}
其实这是还是单次按钮的事件,只不过用了线程而已,但是。。。怎么循环啊。。。
困惑1:如何实现循环,怎么加,用while(true)?还是别的,我在别处看的代码有try,catch的(貌似用异常解决?不懂)
困惑2:如何停止,我编写成带线程的就是为了让他在“次循环”死循环工作下,主线程的UI能够停止(因为要不停的接收单片机传来的字符串,然后显示出来),但貌似是徒劳。。。至少我没成功。。。
问题3:如何更新UI,即,将接受到的字符串不停的显示出来,怎么加,在哪里加。
就这些了。希望大侠们能在我那个代码上面改改。
ps.在下乃非软件专业大学生,兴趣所向,任务所指,投奔c#,无奈四处碰壁,几欲投河,望诸位大侠慷慨解囊,救我于水火之中,小弟不胜感激。
private void button1_Click(object sender, EventArgs e)
{ try
{Thread threadReceive = new Thread(new ThreadStart(DoWork));
if(button1.Text=="开始")
{
threadReceive.Start();
button1.Text="结束";
}
else
{
threadReceive.Abort();
button1.Text=“开始";
}
}
}
public void DoWork()
{while (true)
{Thread.Sleep(1000);
strReceive += "a";
strReceive = "" + strReceive + "\n";
s1 = strReceive;
MyInvokea mi = new MyInvokea(UpdateForm);
this.BeginInvoke(mi, new Object[] { });
}
public void UpdateForm()
{
try
{int s3 = 0;
try
{
s3 = s1.Length;
}
catch { }
if (s3 != 0)
richTextBox1.AppendText(stime + s1);
else
richTextBox1.AppendText(stime);
Gbitlen += bytesRead;
label1.Text =Gbitlen.ToString();
}
catch { }
}
主要的函数改了之后就是这样了(没用的地方精简了一下)循环是解决了,但是还是有问题,就是停不下来啊,点击“开始”按钮后,开始不停的出字儿,然后按钮变成“结束”,然后再次点击“结束”,“结束”变成“开始”,但是仍然不停的出字儿,木有停,谁帮帮忙啊。 展开
这里简化说一下过程与问题:
第一步,做的是按钮触发事件,点击一下,textbox1显示“123”,很简单。
然后,我开始做循环的,即点击一次,循环显示该字符串,我直接在按钮事件下写
while(true){textbox1.Text="123"}的死循环。果真是死循环。。。UI直接无响应。。。上网查询,说是另开线程可以解决死机问题,经历了无数尝试,我终于成功了线程加委托,代码如下:
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(DoWork));
thread.Start();
}
public delegate void MyInvokea();
public void DoWork()
{
MyInvokea mi = new MyInvokea(UpdateForm);
this.BeginInvoke(mi, new Object[] { });
}
public void UpdateForm()
{
this.textBox1.Text = "123";
}
其实这是还是单次按钮的事件,只不过用了线程而已,但是。。。怎么循环啊。。。
困惑1:如何实现循环,怎么加,用while(true)?还是别的,我在别处看的代码有try,catch的(貌似用异常解决?不懂)
困惑2:如何停止,我编写成带线程的就是为了让他在“次循环”死循环工作下,主线程的UI能够停止(因为要不停的接收单片机传来的字符串,然后显示出来),但貌似是徒劳。。。至少我没成功。。。
问题3:如何更新UI,即,将接受到的字符串不停的显示出来,怎么加,在哪里加。
就这些了。希望大侠们能在我那个代码上面改改。
ps.在下乃非软件专业大学生,兴趣所向,任务所指,投奔c#,无奈四处碰壁,几欲投河,望诸位大侠慷慨解囊,救我于水火之中,小弟不胜感激。
private void button1_Click(object sender, EventArgs e)
{ try
{Thread threadReceive = new Thread(new ThreadStart(DoWork));
if(button1.Text=="开始")
{
threadReceive.Start();
button1.Text="结束";
}
else
{
threadReceive.Abort();
button1.Text=“开始";
}
}
}
public void DoWork()
{while (true)
{Thread.Sleep(1000);
strReceive += "a";
strReceive = "" + strReceive + "\n";
s1 = strReceive;
MyInvokea mi = new MyInvokea(UpdateForm);
this.BeginInvoke(mi, new Object[] { });
}
public void UpdateForm()
{
try
{int s3 = 0;
try
{
s3 = s1.Length;
}
catch { }
if (s3 != 0)
richTextBox1.AppendText(stime + s1);
else
richTextBox1.AppendText(stime);
Gbitlen += bytesRead;
label1.Text =Gbitlen.ToString();
}
catch { }
}
主要的函数改了之后就是这样了(没用的地方精简了一下)循环是解决了,但是还是有问题,就是停不下来啊,点击“开始”按钮后,开始不停的出字儿,然后按钮变成“结束”,然后再次点击“结束”,“结束”变成“开始”,但是仍然不停的出字儿,木有停,谁帮帮忙啊。 展开
6个回答
展开全部
private void button1_Click(object sender, EventArgs e)
{ try
{Thread threadReceive = new Thread(new ThreadStart(DoWork));
每次在click的时候都新启动一个线程,当然不能停止了,你想一下,上次new的Thread对象,还是你现在要停止的那个对象吗?
Thread threadReceive; //全局变量
private void button1_Click(object sender, EventArgs e)
{
try
{
if (null == threadReceive)
threadReceive = new Thread(new ThreadStart(DoWork));
if (button1.Text == "开始")
{
if (!threadReceive.IsAlive)
{
threadReceive = new Thread(new ThreadStart(DoWork));
threadReceive.Start();
button1.Text = "结束";
}
}
else
{
if (threadReceive.IsAlive)
{
threadReceive.Abort();
button1.Text = "开始";
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
首先threadReceive作为全局的。其次 线程被Abort后就不能用了,要重新启动一个。这个是一个比较笨的办法,可以考虑线程池。
还有你显示信息的时候应该也会有异常
public void UpdateForm()
{
if (this.InvokeRequired)
{
MyInvokea mi = new MyInvokea(UpdateForm);
this.BeginInvoke(mi, new Object[] { });
}
else
{
try
{
int s3 = 0;
try
{
s3 = s1.Length;
}
catch { }
if (s3 != 0)
richTextBox1.AppendText(stime + s1);
else
richTextBox1.AppendText(stime);
Gbitlen += bytesRead;
label1.Text = Gbitlen.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
在DoWork方法里主动调用UpdateForm就行了
{ try
{Thread threadReceive = new Thread(new ThreadStart(DoWork));
每次在click的时候都新启动一个线程,当然不能停止了,你想一下,上次new的Thread对象,还是你现在要停止的那个对象吗?
Thread threadReceive; //全局变量
private void button1_Click(object sender, EventArgs e)
{
try
{
if (null == threadReceive)
threadReceive = new Thread(new ThreadStart(DoWork));
if (button1.Text == "开始")
{
if (!threadReceive.IsAlive)
{
threadReceive = new Thread(new ThreadStart(DoWork));
threadReceive.Start();
button1.Text = "结束";
}
}
else
{
if (threadReceive.IsAlive)
{
threadReceive.Abort();
button1.Text = "开始";
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
首先threadReceive作为全局的。其次 线程被Abort后就不能用了,要重新启动一个。这个是一个比较笨的办法,可以考虑线程池。
还有你显示信息的时候应该也会有异常
public void UpdateForm()
{
if (this.InvokeRequired)
{
MyInvokea mi = new MyInvokea(UpdateForm);
this.BeginInvoke(mi, new Object[] { });
}
else
{
try
{
int s3 = 0;
try
{
s3 = s1.Length;
}
catch { }
if (s3 != 0)
richTextBox1.AppendText(stime + s1);
else
richTextBox1.AppendText(stime);
Gbitlen += bytesRead;
label1.Text = Gbitlen.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
在DoWork方法里主动调用UpdateForm就行了
展开全部
DoWork里写while循环就可以了。至于停下来的问题,楼主可以在里面加一个原子类型,进行判断,把值改了,该停就停了。这样就不用强行停止线程,也就不需要try catch了。
static int shouldDo = 1;
DoWork(){
while(shouldDo == 1)
{ .......}
}
static int shouldDo = 1;
DoWork(){
while(shouldDo == 1)
{ .......}
}
追问
主要的函数改了之后就是这样了(没用的地方精简了一下)循环是解决了,但是还是有问题,就是停不下来啊,点击“开始”按钮后,开始不停的出字儿,然后按钮变成“结束”,然后再次点击“结束”,“结束”变成“开始”,但是仍然不停的出字儿,木有停,谁帮帮忙啊。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你的线程都没有关。
追问
主要的函数改了之后就是这样了(没用的地方精简了一下)循环是解决了,但是还是有问题,就是停不下来啊,点击“开始”按钮后,开始不停的出字儿,然后按钮变成“结束”,然后再次点击“结束”,“结束”变成“开始”,但是仍然不停的出字儿,木有停,谁帮帮忙啊
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
一个显示的问题,怎么搞的那么复杂。while(true){textbox1.Text="123"}这种写法,很要命的,不管是主线程,还是子线程,你还让不让CPU休息了?你把它放到子线程,主线程虽然不会死掉,但是电脑会像中毒一样卡。
我的建议是,你用一个timer控件,每隔1s或0.5s读取一次单片机的数据,对CPU来讲,休息的时间已经够多了,对用户来讲,数字变化的速度类似于心跳,不会看着眼花。
至于你的Click方法,负责讲timer enable或者disable,自然能起到开始和停止的作用。
做程序员,如果你只会写代码,那只是个IT工人,能做合理设计,才小有前途。
我的建议是,你用一个timer控件,每隔1s或0.5s读取一次单片机的数据,对CPU来讲,休息的时间已经够多了,对用户来讲,数字变化的速度类似于心跳,不会看着眼花。
至于你的Click方法,负责讲timer enable或者disable,自然能起到开始和停止的作用。
做程序员,如果你只会写代码,那只是个IT工人,能做合理设计,才小有前途。
追问
主要的函数改了之后就是这样了(没用的地方精简了一下)循环是解决了,但是还是有问题,就是停不下来啊,点击“开始”按钮后,开始不停的出字儿,然后按钮变成“结束”,然后再次点击“结束”,“结束”变成“开始”,但是仍然不停的出字儿,木有停,谁帮帮忙啊
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
童鞋,我晓得你的做单片机的都喜欢在初始化完成之后就一个while(true)来接收和分配命令,直到单片机关机。不过呢,软件和硬件还是有区别的,这里你完全可以使用Timer执行需要的过程,程序中while(true)如果没有显式地退出,会很快耗光你系统的资源的
追问
主要的函数改了之后就是这样了(没用的地方精简了一下)循环是解决了,但是还是有问题,就是停不下来啊,点击“开始”按钮后,开始不停的出字儿,然后按钮变成“结束”,然后再次点击“结束”,“结束”变成“开始”,但是仍然不停的出字儿,木有停,谁帮帮忙啊
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
1.接受数据建议用异步(如果读取内容的时候有异步操作);否则可以用while(true)来做死循环,但注意适当用Thread.Sleep来做时间片休眠,避免占满整个CPU;try catch不是必须的。
2.什么叫主线程的UI能够停止?
3.收到数据后使用委托让主线程更新界面就行了。
4.不知道你怎么读数据的,也就不知道怎么帮你改了。
2.什么叫主线程的UI能够停止?
3.收到数据后使用委托让主线程更新界面就行了。
4.不知道你怎么读数据的,也就不知道怎么帮你改了。
追问
主要的函数改了之后就是这样了(没用的地方精简了一下)循环是解决了,但是还是有问题,就是停不下来啊,点击“开始”按钮后,开始不停的出字儿,然后按钮变成“结束”,然后再次点击“结束”,“结束”变成“开始”,但是仍然不停的出字儿,木有停,谁帮帮忙啊
追答
如果你使用自己创建的线程来执行操作,那么停止的话可能需要你自己来强行中止线程。建议使用BackgroundWorker,大致如下(仅做例子):
System.ComponentModel.BackgroundWorker bgw = new System.ComponentModel.BackgroundWorker();
protected override void OnLoad(EventArgs e)
{
bgw.DoWork += new System.ComponentModel.DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
private void button1_Click(object sender, EventArgs e)
{
if (!bgw.IsBusy){ bgw.RunWorkerAsync();button1.Text = "停止";}
}
void bgw_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
button1.Text = "开始";
}
void bgw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
System.ComponentModel.BackgroundWorker bgw = sender as System.ComponentModel.BackgroundWorker;
while (!bgw.CancellationPending)
{
//这里循环读取数据。
}
if (bgw.CancellationPending)
{
e.Cancel = true;
}
}
如果读取数据本身是阻塞线程的,那么这样就不适用,最好自己创建后台线程,需要中止的时候强行杀掉。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询