C# - 从工作线程而不是主线程访问时,类字段为空

发布于 2024-08-28 00:32:17 字数 927 浏览 19 评论 0原文

不确定我做错了什么:

class MyClass
{

    private EventInfo eventInfo;

    public void OnGenerateEvent(object sender, EventArgs e)
    { 
        // Called from *main* thread 

        // Load assembly and set eventInfo here
        eventInfo = ....GetEvent(...);
        eventInfo.AddEventHandler(source, handler);

        // Call to a static method in another assembly
        someMethodInfo.Invoke(null, null);

    }


    public void OnEventChanged(object sender, EventArgs args)
    {    
        // Called from a *worker* thread created 
        // by that static method in the other assembly

        eventInfo is null here !   

        // Trying to remove handler
        eventInfo.RemoveEventHandler(.....);

    }


    // But...
    protected override void Dispose(bool disposing)
    {
        // Called from *main* thread when program closes

        eventInfo is *not* null here
    }
}

Not sure what I'm doing wrong:

class MyClass
{

    private EventInfo eventInfo;

    public void OnGenerateEvent(object sender, EventArgs e)
    { 
        // Called from *main* thread 

        // Load assembly and set eventInfo here
        eventInfo = ....GetEvent(...);
        eventInfo.AddEventHandler(source, handler);

        // Call to a static method in another assembly
        someMethodInfo.Invoke(null, null);

    }


    public void OnEventChanged(object sender, EventArgs args)
    {    
        // Called from a *worker* thread created 
        // by that static method in the other assembly

        eventInfo is null here !   

        // Trying to remove handler
        eventInfo.RemoveEventHandler(.....);

    }


    // But...
    protected override void Dispose(bool disposing)
    {
        // Called from *main* thread when program closes

        eventInfo is *not* null here
    }
}

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

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

发布评论

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

评论(2

睡美人的小仙女 2024-09-04 00:32:17

我认为我们需要看到可重现的代码,但我可以看到 4 种情况:

  • 在这两种情况下,您正在与不同的 MyClass 实例对话 - 我的赌注在这里
  • 在其中一个方法中有一个名为 eventInfo 的变量(如果有任何歧义,请尝试使用 this.eventInfo 当您指的是该字段)
  • 写入或读取被缓存(尝试标记字段易失性;再次不太可能)
  • 线程特定的字段(线程本地存储) - 非常不可能

前两个更有可能。

I think we'd need to see reproducible code, but I can see 4 scenarios:

  • you are talking to a different MyClass instance in the two cases - my bet is here
  • you have a variable called eventInfo in one of the methods (try using this.eventInfo when you mean the field if there is any ambiguity)
  • the write or read is cached (try marking the field volatile; again unlikely)
  • a thread-specific field (thread-local storage) - very unlikely

The first two are much more likely.

初心 2024-09-04 00:32:17

您需要至少执行以下操作之一:

  • 使 eventInfo 易失性,以确保 OnGenerateEvent() 在调用 < code>someMethodInfo.Invoke()

  • 使用互斥锁/锁之类的东西来保护对 eventInfo 的访问。这还将提供适当的内存屏障(我认为这才是真正应该做的)

哦,我假设实际上没有涉及 2 个不同的 MyClass 实例 - 那不能通过您所显示的代码进行验证。

You'll need to do at least one of the following:

  • make eventInfo volatile to ensure that OnGenerateEvent() writes it all the way out to memory before calling someMethodInfo.Invoke()

  • use something like a mutex/lock to protect access to eventInfo. This will also provide the proper memory barriers (this is what really should be done in my opinion)

Oh, and I'm assuming that there aren't really 2 different MyClass instances involved - that can't be verified by the code you've shown.

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