首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从后台线程写入,从UI 1读取

从后台线程写入,从UI 1读取
EN

Stack Overflow用户
提问于 2011-04-28 07:44:47
回答 3查看 288关注 0票数 0

我有一个后台线程在做一些工作,还有一个UI显示进度,出于各种原因,我没有使用后台工作人员;相反,Timer会触发对UI的更新。

我根本不使用Invoke调用。相反,后台进程将写入由4个字符串组成的数组。此数组被声明为主窗体的实例成员。

我需要使用锁从UI线程读取这个数组吗?在没有任何额外预防措施的情况下,从后台线程写入数组并从UI线程读取数组可以吗?

编辑:MSDN读取"The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock."。这不意味着锁只会阻止同一代码块由两个不同的线程运行吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-28 07:55:04

你有没有想过,如果读者正在阅读,而作者修改了它,将会发生什么?

您应该在读取器和作者lock中使用

如果您正在访问和修改来自不同线程的任何其他资源,则相同。你应该锁在同一个物体上避免二次效应..。

我在C#中发现的关于线程处理的最好参考是以下书:

C#中的线程化,约瑟夫·阿尔巴哈里著

你会发现有很多这样的例子。

您可以在网上阅读,我建议您这样做,因为它需要许多与多线程相关的主题,比如Monitor.Enter和其他主题。

编辑:

如果您将数据存储在局部变量中只是因为稍后您将通过主线程访问它,我认为这不是最好的选择。您可以使用其他线程修改GUI中的控件,而不存在任何问题,而且这一点也不困难:

而不是做:

代码语言:javascript
复制
public void UpdateTextBox(string text) {
    textBox1.Text = text;
}

你可以:

代码语言:javascript
复制
public void UpdateTextBox(string text) {
    MethodInvoker m = () => { textBox1.Text = text; };

    //The following lines can be encapsulated in a method, in case you need to use it again in other methods...
    if (InvokeRequired) {
        BeginInvoke(m);
    }
    else {
        m.Invoke();
    }
}
票数 1
EN

Stack Overflow用户

发布于 2011-04-28 07:50:01

快速回答是,如果有多个线程同时写入字符串数组,则需要使用锁。下面是指向c# http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=VS.100%29.aspx锁的最新引用的链接。

票数 1
EN

Stack Overflow用户

发布于 2011-04-28 08:01:59

为了澄清,正如我看到您的评论,您必须在写操作周围使用锁语句,在读取器周围使用另一个锁语句。即

代码语言:javascript
复制
//lock sync object in your form 
private object sync = new object();

在写作方法和阅读方法上。

代码语言:javascript
复制
lock (sync)
{
    //access the array here
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5815324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档