从后台线程写入,从UI读取一个

时间:2011-04-28 07:44:48

标签: .net multithreading mono locking

我有一个后台线程做一些工作和显示进度的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."。这是否意味着锁只会阻止同一块代码被两个不同的线程运行?

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

你有没有想过如果读者正在阅读并且作者修改它会发生什么?

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

如果您正在访问&从不同的线程修改任何其他资源,相同。你应该锁定同一个对象以避免次要影响......

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

Threading in C#,Joseph Albahari

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

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

修改
如果您只是将数据存储在本地变量中,因为稍后您将通过主线程访问它,我认为这根本不是最佳选择。您可以使用其他线程在GUI中修改控件而不会出现问题,这一点都不难:

而不是:

public void UpdateTextBox(string text) {
    textBox1.Text = text;
}

你可以这样做:

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();
    }
}

答案 2 :(得分:1)

只是为了澄清,正如我看到你的评论,你必须使用围绕写操作的锁定语句和读者声明周围的另一个锁定语句。即。

//lock sync object in your form 
private object sync = new object();

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

lock (sync)
{
    //access the array here
}