c# - 线程安全属性

标签 c# multithreading

我正在尝试学习 C# 上的线程,但在如何处理属性方面遇到了一些困难。

以我的类 NavigateIE 为例,它一次只能执行一个操作。我想如果我有一个属性很忙,那么我就会知道该实例是否在类外很忙。

class NavigateIE
{
    public bool busy;

    public void IEAction(string action)
    {
        busy = true;

        var th = new Thread(() =>
                {
                    try
                    {
                        //Do stuff

                    }
                    catch(Exception ex)
                    {
                        //report Exception
                    }
                    finally
                    {
                        busy = false;
                    }
                });
        th.SetApartmentState(ApartmentState.STA);
        th.Start();

    }

}

但是,由于 busy = false; 仅在线程内调用,因此这不起作用,因为 navigateIE.busy 始终为 true。

class MainElsewhere
{
    private NavigateIE navigateIE = new NavigateIE();

    private void Main()
    {
     if (!navigateIE.busy)
     {
      //navigateIE.busy always == true
     }
    }

}

我有两个问题:

1) 如何设置该属性,使其成为线程安全的并且 busy = false; 可以在类外看到?

2) 有更好的方法吗?

编辑:本质上,NavigateIE 是一个使用 Watin 处理单个 IE 实例的类。如果没有其他方法正在运行,我只能在 NavigateIE 中调用一个方法,否则之前的操作尚未完成。 NavigateIE 是从计时器计时的主要方法调用的,因此我需要检查类是否繁忙。

第一次 navigateIE.busy == false 但线程将其设置回 false 后,main 方法仍然看到 navigateIE.busy == true。

最佳答案

你这样做根本是错误的。是的,busy 很可能是真的,该线程将在现代多核处理器上快速开始运行。没有实际的保证,它只是很常见。它何时返回到 false 也是高度不可预测的,这取决于线程的作用。包括never,bool 不是同步原语。

我不清楚你想要达到什么目的,但你实际上根本不需要使用忙标志。 IE 是一个单元线程 COM 对象,它已经自动编码对拥有该对象的 STA 线程的调用。从另一个线程调用它的 Navigate() 方法很好,不需要额外的代码来提供帮助。如果您需要一个繁忙的标志来指示浏览器正在执行命令,那么您将需要一个在实际开始导航时而不是在启动线程时设置为 true 的标志。利用 this answer 中的代码,也许。

关于c# - 线程安全属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20011919/

相关文章:

python - 在Python中让线程休眠直到特定时间

c# - 在 Xamarin.Forms 上制作一组动态的 3 个选择器

c# - 大 Switch 语句 : Bad OOP?

c# - SAP 企业服务工作区

c++ - _beginthreadex 无法从 'overloaded-function' 转换

multithreading - MapReduce - 除了字数统计还有别的吗?

c# - 统一蹲下时,旋转播放器上的相机晃动

c# - 使用 Json.NET 将多个类的对象序列化为单个 JSON

java - 待澄清的简单多线程代码

c++ - 多线程使用者使用boost ringbuffer不产生与输入相同的输出