如何解決 C#WinForm專案中使用控制元件較多時出現重繪問題

,具體如下 圖:
uj5u.com熱心網友回復:
如果程式沒毛病,界面設計合理,這種只有考慮換一臺性能好點(顯存,記憶體大些)的機子了。uj5u.com熱心網友回復:
控制元件太多,如果要求必須一次加載,最好給個進度潭訓提示資訊;如果沒有強制性要求,按照功能分個類,
在左側加導航樹,把不同的控制元件放到不同的Tab中去。
uj5u.com熱心網友回復:
與 UI 無關的處理應該單獨、異步執行,然后當執行完畢之后才呼叫主執行緒來更新界面。例如測驗下面的例子:using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void button1_Click(object sender, EventArgs e)
{
button1.Text = "測驗開始";
Test();
}
void Test()
{
Thread.Sleep(10000);
this.button1.Text = "測驗完成";
}
}
}
當你點擊按鈕的時候,你會發現10秒鐘之內界面卡死了,視窗根本用滑鼠拖動不了!這就是很糟糕的程式。而改成
using System;你會發現在耗時程序執行程序中也能自由地拖動視窗。
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
async void button1_Click(object sender, EventArgs e)
{
button1.Text = "測驗開始";
await Test();
this.button1.Text = "測驗完成";
}
Task Test()
{
return Task.Run(() => //把與UI重繪無關的陳述句放到這個匿名委托中執行
{
Thread.Sleep(10000);
});
}
}
}
假設在異步并發程序中要修改視窗控制元件,那么需要使用委托來訪問控制元件。例如:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
async void button1_Click(object sender, EventArgs e)
{
button1.Text = "測驗開始";
await Test();
this.button1.Text = "測驗完成";
}
Task Test()
{
return Task.Run(() => //把與UI重繪無關的陳述句放到這個匿名委托中執行
{
Thread.Sleep(2500);
this.button1.BeginInvoke((Action)delegate
{
this.button1.Text = "1";
});
Thread.Sleep(2500);
this.button1.BeginInvoke((Action)delegate
{
this.button1.Text = "2";
});
Thread.Sleep(2500);
this.button1.BeginInvoke((Action)delegate
{
this.button1.Text = "3";
});
Thread.Sleep(2500);
});
}
}
}
這里,在耗時的異步程序執行程序中訪問了 UI 界面控制元件,就需要使用 BeginInvoke 委托來操作控制元件,使用 BeginInvoke.Invoke 委托來操作控制元件,這是15年前就在 .net 中有的操作規范。
uj5u.com熱心網友回復:
簡單總結一下,就是,其實你絕大部分時間是用與界面 UI 無關的操作把人家 UI 執行緒給“卡死了、阻塞了”,造成界面看起來死了一樣。其實界面可以很靈敏,可以隨時重繪、可以迅速回應各種事件。不是程式形能不好,都是設計者的知識、是人為惹的禍。uj5u.com熱心網友回復:
樓上答非所問啊。人家問的是控制元件多顯示卡頓,注意審題。uj5u.com熱心網友回復:
sp1234已經回答了。重點就是資料讀取,UI系結這些操作,變為異步。
如果說某些sql需要優化之類的,就不細說了。
大綱還是主執行緒和異步分離。
uj5u.com熱心網友回復:
人家說控制元件多,顯示卡頓,沒有說因為讀取后臺資料導致界面假死,你們都不審題嗎
uj5u.com熱心網友回復:
我不知道你明不明白。。。
主執行緒UI系結資料才是導致界面卡頓的主要元兇。
所以我們說這個靠異步去解決。
uj5u.com熱心網友回復:
sp1234已經回答了。
重點就是資料讀取,UI系結這些操作,變為異步。
如果說某些sql需要優化之類的,就不細說了。
大綱還是主執行緒和異步分離。
人家說控制元件多,顯示卡頓,沒有說因為讀取后臺資料導致界面假死,你們都不審題嗎
每個人審題的側重點,本來就有區別。
怎么斷定你認為的是對的,只有等樓主確認了才知道。
uj5u.com熱心網友回復:
與 UI 無關的處理應該單獨、異步執行,然后當執行完畢之后才呼叫主執行緒來更新界面。例如測驗下面的例子:using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void button1_Click(object sender, EventArgs e)
{
button1.Text = "測驗開始";
Test();
}
void Test()
{
Thread.Sleep(10000);
this.button1.Text = "測驗完成";
}
}
}
當你點擊按鈕的時候,你會發現10秒鐘之內界面卡死了,視窗根本用滑鼠拖動不了!這就是很糟糕的程式。而改成using System;你會發現在耗時程序執行程序中也能自由地拖動視窗。
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
async void button1_Click(object sender, EventArgs e)
{
button1.Text = "測驗開始";
await Test();
this.button1.Text = "測驗完成";
}
Task Test()
{
return Task.Run(() => //把與UI重繪無關的陳述句放到這個匿名委托中執行
{
Thread.Sleep(10000);
});
}
}
}
假設在異步并發程序中要修改視窗控制元件,那么需要使用委托來訪問控制元件。例如:using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
async void button1_Click(object sender, EventArgs e)
{
button1.Text = "測驗開始";
await Test();
this.button1.Text = "測驗完成";
}
Task Test()
{
return Task.Run(() => //把與UI重繪無關的陳述句放到這個匿名委托中執行
{
Thread.Sleep(2500);
this.button1.BeginInvoke((Action)delegate
{
this.button1.Text = "1";
});
Thread.Sleep(2500);
this.button1.BeginInvoke((Action)delegate
{
this.button1.Text = "2";
});
Thread.Sleep(2500);
this.button1.BeginInvoke((Action)delegate
{
this.button1.Text = "3";
});
Thread.Sleep(2500);
});
}
}
}
這里,在耗時的異步程序執行程序中訪問了 UI 界面控制元件,就需要使用 BeginInvoke 委托來操作控制元件,使用 BeginInvoke.Invoke 委托來操作控制元件,這是15年前就在 .net 中有的操作規范。
滿分!!!!!!!!!!!!!!!!!!!!!!!!!!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/74865.html
標籤:C#
上一篇:C# 手寫影像復制原始碼
