【问题标题】:Access Shared Variable in Threading在线程中访问共享变量
【发布时间】:2021-08-12 03:11:04
【问题描述】:

我正在使用下面的代码并在 foeach 循环中使用 Task.Run 以便每个循环都可以并行运行,因为我在 foreach 循环中有一些逻辑需要一些时间,但我面临的问题是 tContext.SecondNodeId =其他节点;有时打印为 10 或 11 ,我想按前 10 后 11 的顺序打印,因为我还有一些代码,这些值对逻辑很重要。

class Program
{
    static void Main(string[] args)
    {
        TempData tContext = new TempData();
        var nodes = new List<int>() { 1, 2, 3, 4, 5, 6 };
        var otherNodes = new List<int> { 10, 11 };
        foreach (var node in nodes)
        {
            tContext.firstNodeId = node;
            List<Task> tasks = new List<Task>();
            foreach (var otherNode in otherNodes)
            {
                Task t = Task.Run(() =>
                {
                   
                     tContext.SecondNodeId = otherNode;
                    Console.WriteLine("First Node id is" + tContext.firstNodeId + "Second Node Id is " + tContext.SecondNodeId);
                    // I have some long running code which uses first node and second node id.
                });
                tasks.Add(t);
            }
            Task.WaitAll(tasks.ToArray());
        }
    }
}

请提出一种实现方法。

下面是输出。

【问题讨论】:

    标签: c# .net multithreading thread-safety threadpool


    【解决方案1】:

    在您调用的内部循环中
    Task t = Task.Run(() =&gt;...);

    在另一个线程上运行 lambda。在这个 lambda 中,您正在设置:

    tContext.SecondNodeId = otherNode;

    然后从这个值中读取。因为您有多个线程写入该值,所以它可以在值 10 和 11 之间切换,具体取决于它们执行所需的时间。换句话说,内部循环可以在生成的任务执行之前执行多次迭代。这就是所谓的“竞争条件”。

    假设第一个内部循环迭代执行,任务到达设置tContext.SecondNodeId =10 的位置。在这一行之后,完全有可能循环的第二次迭代刚刚完成,并且生成的任务会将其设置为 11。然后当第一个任务的其余部分执行时,它将使用值 11 而不是 10。

    一种解决方法是使用局部变量:

    var secondNodeId = otherNode;

    并在您的 lambda 中使用它。这不能被其他任务访问,也不会改变。

    【讨论】:

    • 感谢您的澄清,如果我将使用本地变量,我将无法使用我想设置 tcontext.secondnodeId 的对象属性。我们可以使用锁定或任何其他方式来实现它,以便我可以使用我的类对象。
    • 您可以从您的任务中返回一个值,然后使用它来设置该值。另一种方法是创建一个锁定对象并锁定您修改变量的点。请注意,这需要是所有修改它的任务都使用的单个锁对象,因此可能可以在方法开始时创建。
    • 我尝试使用 lock 但我仍然可以看到两个 id 相同.. private static readonly object ob = new object();锁定 (ob) { tContext.SecondNodeId = otherNode; }
    • 您必须发布完整的代码以显示您如何访问该变量,以便我说出它为什么不起作用。
    • codeshare.io/5PZDXP此链接中的共享代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 2018-08-28
    • 2017-09-10
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多