C#多线程启动后UI界面无响应

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Da... using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WinPCapTest
{
public partial class Form1 : Form
{
static Boolean flag = false;
public Form1()
{
InitializeComponent();

}
private void IDC_NETCARD_Click(object sender, EventArgs e)
{
}

private void IDC_START_Click(object sender, EventArgs e)
{
flag = true;
Thread thread = new Thread(new ThreadStart(Test));
thread.IsBackground = true;
thread.Start(); }

private void IDC_STOP_Click(object sender, EventArgs e)
{
flag = false;
}

delegate void add();
public void Test()
{
this.BeginInvoke(new add(DoWork));
}
//工作者方法
public void DoWork()
{
int i = 0;
while (flag == true)
{
this.IDC_TEXT.AppendText((i++) + "\r\n");
this.IDC_TEXT.ScrollToCaret();
Thread.Sleep(1000);
}
i = 999;
}
}
}

预想:界面上有一个文本框,用来显示递增的数字的(示例用)。还有两个按钮(START\STOP),按START启动工作者线程,按STOP停止工作者线程。
但是目前运行起来后,START可以启动线程,但是起来之后,界面就不能移动,点STOP也没反应了。
求教高手怎么解决这个问题。
展开
 我来答
可以叫我表哥
2015-10-17 · 知道合伙人数码行家
可以叫我表哥
知道合伙人数码行家
采纳数:25897 获赞数:1464972
2010年毕业于北京化工大学北方学院计算机科学与技术专业毕业,学士学位,工程电子技术行业4年从业经验。

向TA提问 私信TA
展开全部
程序启动的时候会建立一个主线程,这个线程叫UI线程,从字面理解就可以知道这个线程专门处理有关UI(也就是界面)所有的事件。界面卡是因为,你进入了比如点击事件里面,线程一直在处理这个任务,这个任务一直没返回,也就是这个方法一直没返回。所以这个时候你点击界面是没反应的,也就是假死状态。

如果需要处理一个长时间的任务,应该建立一个新线程B去处理。同时B要去修改界面的话,需要用委托。因为界面是主线程负责,用委托是把修改界面这个动作交给主线程去做,如果由B去做的话可能会造成死锁之类问题

C#从另外一个线程操作windows窗体上的控件,必须要使用委托,通过委托调用UI线程去操控控件

//这个是窗体线程MainFrm

public delegate void Delegate_ChangeCallBack(string _value);
public Delegate_ChangeCallBack dlg_Change;
public static MainFrm mainFrm;

private void MainFrm_Load(object sender, EventArgs e)
{
mainFrm = this;

dlg_Change = new Delegate_ChangeCallBack (ChangeUI);
}

private void ChangeUI(string _value)
{
this.txt_Change.text = _value;

//do something...

}
private void button1_Click(object sender, EventArgs e)//下面是你的新线程
{
Client c = new Client();
Thread newThread = new Thread(new ParameterizedThreadStart(c.NewThread());
newThread.Name = "Door2 Conn Thread:" + mission.Id;
newThread.IsBackground = true;
newThread.Start();
}
Class Client
{

private void NewThread()
{
string _Id = "change";

MainFrm.mainFrm.BeginInvoke(MainFrm.mainFrm.dlg_Change , new object[] { _Id });
}
}
哲事姓无
2013-01-02 · TA获得超过1176个赞
知道小有建树答主
回答量:903
采纳率:100%
帮助的人:431万
展开全部
因为你的界面的大部分时间被阻塞在sleep(1000)上了。

当线程调动后,你启用了BeginInvoke去执行DoWork时,DoWork函数即在当前界面所在线程执行工作了,只有当DoWork执行完毕后你的界面才得到执行的机会,这时才会有影应。

请不要在整个函数使用BeginInvoke或是invoke来调用,而应该在执行界面相关的操作的时候(比如对idc_text执行操作时)才使用BeginInvoke或是invoke。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
路有时不在脚下
2013-01-07 · 超过25用户采纳过TA的回答
知道答主
回答量:135
采纳率:0%
帮助的人:34.9万
展开全部
没有看明白你用多线程要实现什么效果?你声明DoWork()方法是在主线程执行的,不是在你声明的副线程中执行,那界面怎么会动呢?
你执行了一个副线程,起到的作用就是执行了Test()方法,没有停留就转到了主线程执行DoWork()方法了,实际效果:相当于点击开始执行的是DoWork()方法。
如果你想使用多线程实现数字隔一秒刷新一次,那么你的循环代码应该放到Test()方法中。
OK。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
草薙在
2013-01-02 · TA获得超过4795个赞
知道大有可为答主
回答量:6187
采纳率:50%
帮助的人:6251万
展开全部
实在想不明白你异步启动了一个Thread又调用BeginInvoke让代码在UI线程上同步执行是为什么……
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式