【问题标题】:C# Thread Parameters change during thread execution - why?C# 线程参数在线程执行期间发生变化 - 为什么?
【发布时间】:2010-08-05 16:48:03
【问题描述】:

所以我有一个方法可以获取 List 的字典,然后循环遍历字典的键并将每个 List 传递给单独的线程。

这是一些代码/伪代码:

public static void ProcessEntries() {

    Dictionary<string, List<myObj>> myDictionary = GetDictionary();

    foreach(string key in myDictionary.keys)
    {

        List<myObj> myList = myDictionary[key];

        Thread myThread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() {

            ProcessList(myList);

        }    
    }
}

public static void ProcessList(List<myObj> myList) {

    // Process entries
    // read-only operations on myList

}

问题是在 ProcessList 的执行过程中 myList 参数只是改变了。

我在踢线程之前遍历了列表,然后立即进入线程,我发现结果有所不同。

我已经通过将 Dictionary 变量设置为全局变量来解决了这个问题(我认为!)。使用 [ThreadStatic] 属性是可能的修复列表中的下一个。

我真正想知道的是,当 myList 对象在 ProcessEntries() 中重新分配时,为什么 myList 对象会在 ProcessList() 中发生变化?这不是两个不同的列表吗?如果默认情况下所有参数传递都是按值传递的,为什么 ProcessList() 函数没有 myList 的本地副本? (是吗?)

有没有办法指定您希望将参数传递给线程,并且在执行期间不让父线程或其他线程更改它? (这类似于全局变量的 [ThreadSafe] 属性)

【问题讨论】:

  • 您确定您的代码/伪代码正确且完整吗?据我所知,虽然您对发生的事情的假设是错误的,但看起来代码应该可以正常工作。

标签: c# multithreading parameter-passing threadstatic


【解决方案1】:

我怀疑您的伪代码实际上并不能准确反映您的真实代码。我怀疑您的真实代码如下所示:

foreach(var pair in myDictionary)
{
    Thread myThread = new Thread(delegate() {
        ProcessList(pair.Value);
    });
    myThread.Start();
}

如果是这种情况,问题在于 pair 变量正在被捕获 - 所以当您的线程启动时,它可能指的是不同的键/值对。

修复它的方法是让代码更像你的伪代码:

foreach(var pair in myDictionary)
{
    // You'll get a new list variable on each iteration
    var list = pair.Value;
    Thread myThread = new Thread(delegate() {
        ProcessList(list);
    });
    myThread.Start();
}

更多信息请参见Eric Lippert's blog post on this。

如果这不是问题所在,请给出一个真实的示例而不是伪代码。 short but complete example demonstrating the problem 是理想的选择。

【讨论】:

    【解决方案2】:

    还要确保其他线程不会影响您尝试使用的线程。一定要使用锁和监视器...就在几周前遇到了一些问题..

    【讨论】:

      【解决方案3】:

      在这种情况下,您通过值传递 引用,因此,如果您在某处修改它,它会因地而异。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-05
        • 2021-07-25
        • 1970-01-01
        • 1970-01-01
        • 2021-05-08
        • 2017-11-18
        • 1970-01-01
        相关资源
        最近更新 更多