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

发布于 2024-11-03 15:43:15 字数 368 浏览 2 评论 0原文

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

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

我是否需要使用锁来从 UI 线程读取该数组?从后台线程写入数组并从 UI 线程读取数组而不采取任何额外的预防措施是否可以?

编辑:MSDN读取“lock关键字通过获取给定对象的互斥锁、执行语句,然后释放锁来将语句块标记为关键部分。”< /代码>。这是否意味着锁只会阻止同一代码块被两个不同的线程运行?

I have a background thread doing some work and a UI displaying the progress, and for various reasons, I'm not using a background worker; instead, a Timer triggers updates to the UI.

I'm not using Invoke calls at all. Instead, the background process writes to an array of 4 strings. This array is declared as an instance member of my main form.

Do I need to use locks to read this array from the UI thread? Is it fine to write to the array from the background thread and read from it from the UI one without any extra precautions?

EDIT: MSDN reads "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.". Doesn't that mean that the lock will only prevent the same block of code from being run by two different threads?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

这个俗人 2024-11-10 15:43:15

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

您应该在读取器和写入器中使用lock

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

我发现的有关 C# 中一般线程的最佳参考是以下书籍:

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

Have you thought about what will happen if the reader is reading and the writer modifies it?

You should use lock, both in the reader and the writer.

If you are accessing & modifying any other resource from different threads, the same. You should lock on the same object to avoid secondary effects...

The best reference I have found about threading in general in C# is the following book:

Threading in C#, by Joseph Albahari

You will find there lots of examples like that one.

You can read it online, and I suggest you to do it, because it takes many topics related to multithreading, like Monitor.Enter and others

Edit:
If you are storing data in a local variable only because you will access to it by the main thread later, I don't think that is the best option at all. You can modify your controls in the GUI without problem using another threads, and it isn't difficult at all:

Instead of doing:

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

you can do:

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();
    }
}
两人的回忆 2024-11-10 15:43:15

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

The quick answer is that you need to use locks if you have multiple threads that are writing to your array of strings at the same time. Here is a link to the latest reference on locks for c# http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=VS.100%29.aspx.

晨敛清荷 2024-11-10 15:43:15

只是为了澄清,正如我看到您的评论一样,您必须在写入操作周围使用一个锁定语句,并在读者陈述周围使用另一个锁定语句。即

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

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

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

Just to clarify, as i saw your comment, you must use a lock statement around the write operation AND a another lock statements around the reader satements. i.e.

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

in the writing method and in the reading method.

lock (sync)
{
    //access the array here
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文