惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
F
Full Disclosure
Cloudbric
Cloudbric
Blog — PlanetScale
Blog — PlanetScale
W
WeLiveSecurity
N
News and Events Feed by Topic
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
B
Blog
GbyAI
GbyAI
C
Check Point Blog
B
Blog RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Recorded Future
Recorded Future
The Last Watchdog
The Last Watchdog
N
News and Events Feed by Topic
T
The Blog of Author Tim Ferriss
O
OpenAI News
V
V2EX
人人都是产品经理
人人都是产品经理
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
WordPress大学
WordPress大学
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Security @ Cisco Blogs
C
Cisco Blogs
Security Latest
Security Latest
S
Security Affairs
V
Visual Studio Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
Last Week in AI
Last Week in AI
AWS News Blog
AWS News Blog
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
博客园_首页
U
Unit 42
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
L
LINUX DO - 热门话题
H
Hacker News: Front Page

博客园 - antony.net

移动版网页自动缩放问题 2011年国内五款值得关注网店系统 Enterprise Architect 7 入门教程大全 Enterprise Architect 业务过程建模 不同浏览器处理后退的一些异同 - antony.net - 博客园 23个.NET开源项目 mysql 存储过程 游标 js代码库 table css 固定表头 - antony.net Hash Tables in Javascript RSClientPrint打印 统计sql语句 文档格式批量转换(doc,txt,pdf等) 了解HTTP Headers的方方面面 XmlSerializer 常见问题疑难解答 webservices 水晶报表 - antony.net - 博客园 Build a Custom RadioButton Cell and Column for the DataGridView Control .NET 2.0 - WinForm Control - DataGridView 编程36计(二)
在非UI线程中改变UI控件属性的通用方法
antony.net · 2010-10-10 · via 博客园 - antony.net

转自:http://www.sunnychen.org/trackback.asp?tbID=124&action=addtb&tbKey=43c0d85c8d6d5dcc018d174276ac098da9245500

在.NET中如需在非UI线程中改变UI控件属性时,CLR会抛出异常,提示无法在非UI线程中更新界面上的控件(Cross-thread operation not valid)。一般情况下有两种解决办法。第一种就是设置Control的静态属性CheckForIllegalCrossThreadCalls为False,如下:

03     InitializeComponent();
04     Control.CheckForIllegalCrossThreadCalls = false;
07 private void button1_Click(object sender, EventArgs e)
09     Thread thread = new Thread(() =>
11         for (int i = 0; i < 100000; i++)
13             label1.Text = i.ToString();
14             label1.Refresh();

另一种办法,就是使用委托,根据控件的InvokeRequired属性判断当前控件的更新操作是否是在另一个线程中。如果是,则使用委托进行方法调用并更新控件。但是这种方法有个缺点,就是需要针对每个控件的属性设置方式创建一些单独的委托和方法,这些委托和方法仅仅是在解决跨线程操作的时候使用。比如,你在另一个线程中需要修改某个label的text时,你就需要创建一个SetLabelText方法,假设你还需要更新TextBox的text,那么你还需要另外创建一个SetTextBoxText方法。

通过下面的委托和方法的定义,我们实现了“一次定义,多次使用”。请看:

01 private delegate void ParameterizedControlUpdate(params object[] args);
03 private delegate void ControlUpdateDelegate(Component c,
04     ParameterizedControlUpdate callback,
05     params object[] args);
07 private void DelegatedControlUpdate(Component c,
08     ParameterizedControlUpdate callback,
09     params object[] args)
11     Control target = (c is Control) ? (c as Control) : this;
12     if (target.InvokeRequired)
14         ControlUpdateDelegate d = DelegatedControlUpdate;
15         target.Invoke(d, new object[] { c, callback, args });
19         callback(args);

于是,上面的例子可以改为:

01 private void button1_Click(object sender, EventArgs e)
03     Thread thread = new Thread(() =>
05         for (int i = 0; i < 100000; i++)
07             DelegatedControlUpdate(label1, args =>
09                     label1.Text = (string)args[0];
10                     label1.Refresh();
11                 }, i.ToString());