C#多线程问题 1.对于在子线程操作Ui控件需要返回到ui线程上操作,如果这操作量很大,界面不卡也是难事。2.推荐使用backgroudworker控件,很标准的一个ui线程和子线程交互的一个控件 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 不管是Invoke或者是BeginInvoke作用都是能回到控件对应线程执行操作。BeginInvoke其实还跟EndInvoke对应。你这个需求条例说得不清楚~~无法理解……for(int i=0;i<100;i++){ThreadPool.QueueUserWorkItem((obj) =>{ // 在线程中做耗时的操作,这样就不会造成界面卡死的现象。 int index = (int)obj; Label label = new Label(); label.Font = new Font("宋体", rd.Next(1, 16) + rd.Next(0, 10) * 0.1F, FontStyle.Regular, GraphicsUnit.Pixel, (byte)134); label.Location = new Point(x, y); label.Size = new Size(80, 23); label.Text = index.ToString(); x = 5 + (index % numX) * 85; y = 5 + (index / numX) * 25; this.BeginInvoke(new Action(() => { // 最后再调用异步回调UI线程添加控件。 this.Controls.Add(label); }));}} 根据我个人的理解和使用Invoke\BeginInvoke的感受:其实他们的实质还是把控制权交回给了主线程,所以如果线程耗时较长的话,界面还是会有假死现象... 我想在主线程中新建一个线程创建一个窗口,然后在这个窗口里面有个datagridview,我要在里面动态添加行,我不需要修改主界面的UI控件,其中我这个线程是在主界面的一个for循环下面写的,而我这个for循环是写在一个定时器里面的 假设我已经理解你的意思,嘿嘿:// Form1窗体private void timer1_Tick(object sender, EventArgs e){ for (int i = 0; i < 1; i++) { new Thread(() => { // 启动线程为Form2加载数据 frm2.LoadData(this.GetDataTable()); }).Start(); }}在Form2中public void LoadData(DataTable data){ // 从刚才的代码看出这里应该还是处于Timer所开的线程中 dataGridView1.Invoke(new Action<DataTable>((dt) => { // 加载数据。 dataGridView1.DataSource = dt; }), data);}而最后想说的是如果这样会导致界面卡的话,应该是数据太多,DataGridView在加载的时候会卡住。考虑下分页显示之类的。或者使用Dev的GridControl也能加载大数据。 你没明白同步跟异步跟线程的问题。同步跟异步只是在执行的时间点不同而已,两者都是在同一个线程的,所以在这里同步做了会卡死的异步也会。这里要解决你这个问题是,如何在线程中加载数据(但不刷新),然后回调到主线程刷新(数据一多可能刷新还是会卡)。DataGridView相当于你一赋值DataSource就会触发Invalidate事件,然后刷新,而数据量大的情况这个过程就会很长。这里它自己涉及到UI控件的调用,所以需要在对应的UI线程。试试这个?DataGridView 加载大数据 你没明白同步跟异步跟线程的问题。同步跟异步只是在执行的时间点不同而已,两者都是在同一个线程的,所以在这里同步做了会卡死的异步也会。这里要解决你这个问题是,如何在线程中加载数据(但不刷新),然后回调到主线程刷新(数据一多可能刷新还是会卡)。DataGridView相当于你一赋值DataSource就会触发Invalidate事件,然后刷新,而数据量大的情况这个过程就会很长。这里它自己涉及到UI控件的调用,所以需要在对应的UI线程。试试这个?DataGridView 加载大数据异步不是要多线程同时处理? 添加个窗口方法private void AddRow(object arg){ if (this.InvokeRequired) { this.Invoke(new Action<object>((object arg1) => { this.AddRow(arg1); }), arg); } else { // TODO: AddRow }} 怎样获得你在datagridview中选中的值的索引号 C#怎么获取QQ头像及等级? C# 内存Form截图问题 C# 调用RAR.exe 加密文件夹 一点小问题? 正则表达式,入门级问题! 【跪求】前些天通宵工作,今天又遇TreeView新问题。高手帮忙,否则又得通宵。【跪求】 再一次提问:到底如何在另一个线程类中修改界面中的控件内容 在线等候!!!着急!!! Windows 服务有关问题,请高手们快点进来看看 添加记录的方法一般用哪一种呢? webform 和MVC4混用出现问题。 C#获取Excel有数据的列的列标
你这个需求条例说得不清楚~~无法理解……for(int i=0;i<100;i++){
ThreadPool.QueueUserWorkItem((obj) =>
{
// 在线程中做耗时的操作,这样就不会造成界面卡死的现象。
int index = (int)obj;
Label label = new Label();
label.Font = new Font("宋体", rd.Next(1, 16) + rd.Next(0, 10) * 0.1F, FontStyle.Regular, GraphicsUnit.Pixel, (byte)134);
label.Location = new Point(x, y);
label.Size = new Size(80, 23);
label.Text = index.ToString();
x = 5 + (index % numX) * 85;
y = 5 + (index / numX) * 25; this.BeginInvoke(new Action(() =>
{
// 最后再调用异步回调UI线程添加控件。
this.Controls.Add(label);
}));
}
}
private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < 1; i++)
{
new Thread(() =>
{
// 启动线程为Form2加载数据
frm2.LoadData(this.GetDataTable());
}).Start();
}
}在Form2中public void LoadData(DataTable data)
{
// 从刚才的代码看出这里应该还是处于Timer所开的线程中
dataGridView1.Invoke(new Action<DataTable>((dt) =>
{
// 加载数据。
dataGridView1.DataSource = dt;
}), data);
}
而最后想说的是如果这样会导致界面卡的话,应该是数据太多,DataGridView在加载的时候会卡住。考虑下分页显示之类的。
或者使用Dev的GridControl也能加载大数据。
同步跟异步只是在执行的时间点不同而已,两者都是在同一个线程的,所以在这里同步做了会卡死的异步也会。这里要解决你这个问题是,如何在线程中加载数据(但不刷新),然后回调到主线程刷新(数据一多可能刷新还是会卡)。
DataGridView相当于你一赋值DataSource就会触发Invalidate事件,然后刷新,而数据量大的情况这个过程就会很长。这里它自己涉及到UI控件的调用,所以需要在对应的UI线程。试试这个?DataGridView 加载大数据
同步跟异步只是在执行的时间点不同而已,两者都是在同一个线程的,所以在这里同步做了会卡死的异步也会。这里要解决你这个问题是,如何在线程中加载数据(但不刷新),然后回调到主线程刷新(数据一多可能刷新还是会卡)。
DataGridView相当于你一赋值DataSource就会触发Invalidate事件,然后刷新,而数据量大的情况这个过程就会很长。这里它自己涉及到UI控件的调用,所以需要在对应的UI线程。试试这个?DataGridView 加载大数据异步不是要多线程同时处理?
{
if (this.InvokeRequired)
{
this.Invoke(new Action<object>((object arg1) => {
this.AddRow(arg1);
}), arg);
}
else
{
// TODO: AddRow
}
}