C# 并行循环问题

发布于 2024-11-08 13:38:18 字数 1150 浏览 0 评论 0原文

当此代码运行时,向我显示此错误:“对象引用未设置到对象的实例” 第一行发生错误=> MinorDBDataContext mdc = new ...

但也可以使用串行 for(int i; i < 1005; i++) { } ” 来正常工作。

有什么问题吗?

Thread.CurrentThread.Priority = ThreadPriority.Highest;
        var query = from M in new MajorDBDataContext().User_Accounts select M;
        List<User_Account> Ulist = query.ToList();
        string d = DateTime.Now.ToString();
        int c = 0;
        string temp ="";
        Parallel.For(0, 1005, (i,loop) =>
        {
                try
                {
                    MinorDBDataContext mdc = new MinorDBDataContext(_Filings.OnServerRepository(Ulist[i].user_Sys_DBPath));
                    GoodJob(mdc, temp, i);
                    DA.Page page = mdc.Pages.Single();
                    temp += mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Email;
                    temp += mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Name;
                    temp += mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Family + i.ToString();
                }
                catch { }
        });
        append(temp);

When this Codes Runs show me This error: "Object reference not set to an instance of an object"
error occur in first line => MinorDBDataContext mdc = new ...

but also with serial for "for(int i; i < 1005; i++) { } " works fine.

what's the problem ?

Thread.CurrentThread.Priority = ThreadPriority.Highest;
        var query = from M in new MajorDBDataContext().User_Accounts select M;
        List<User_Account> Ulist = query.ToList();
        string d = DateTime.Now.ToString();
        int c = 0;
        string temp ="";
        Parallel.For(0, 1005, (i,loop) =>
        {
                try
                {
                    MinorDBDataContext mdc = new MinorDBDataContext(_Filings.OnServerRepository(Ulist[i].user_Sys_DBPath));
                    GoodJob(mdc, temp, i);
                    DA.Page page = mdc.Pages.Single();
                    temp += mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Email;
                    temp += mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Name;
                    temp += mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Family + i.ToString();
                }
                catch { }
        });
        append(temp);

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

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

发布评论

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

评论(1

晨光如昨 2024-11-15 13:38:18

您的异常可能表明其他事情。哪个值实际上是 null?你不说。

我可以看到这段代码存在一些问题。

您不能依赖于循环的顺序,但在整个并行代码中都有 temp += (依次将字符串添加到现有字符串,然后将该字符串分配回原始变量)。温度在并行循环之外设置。这是非常危险的。滥用共享状态/数据/资源是多线程代码中最常见的错误之一。

temp 可能会不按顺序添加值。多个内容将同时添加到 temp 中,因此 temp 可能最终会丢失信息,因为 temp 被多个线程覆盖。

_Filings 来自哪里?它是什么?

您可能想在循环内创建一个新的 temp string 并在其中添加所有内容,将最终的temp 添加到 ConcurrentBag (您在循环外部创建的)在每次迭代中。然后,在并行循环之外,您可以迭代 ConcurrentBag 并在安全的环境中构建最终字符串。

根据评论更新
评论:

System.Web.HttpContext.Current.Server.MapPath
使用且 HttpContext.Current 为 null
在多线程循环中。

原因是您现在位于与当前 HttpContext 不同的线程上,因此它无法为您回答任何问题。您必须将上下文传递给并行任务或其中的各个值。我不知道这在并行环境中有多危险。

HttpContext myContext = HttpContext.Current;

在并行循环中使用 myContext 而不是 HttpContext.Current

我不建议这样做,因为领域(如数据层)中的 HttpContext 知识会建立不必要的耦合并使应用程序非常难以维护。要推荐更好的解决方案,需要将您的应用程序分解得更多,这在论坛发帖中是可行的。然而,目前它应该会让你再次行动起来。

Your Exception may be indicative of other things. Which value is actually null? you don't say.

I can see some problems with this code.

You cannot depend on the sequence of the loop, yet you have temp += (sequentially adding a string to the an existing string then assigning the string back to the original variable) throughout the parallelised code. Temp being set up outside the parallel loop. This is very dangerous. Misuse of shared state/data/resources is one of the most common faults in multi-threaded code.

temp may have the values added out of sequence. Multiple things will be added to temp simultaneously, and thus temp may end up missing information because temp is being overwritten from multiple threads.

Where does _Filings come from? What is it?

You may want to create a new temp string inside the loop and add everything there, adding the final temp to a ConcurrentBag (which you create outside the loop) in each iteration. Afterwards, outside of the parallel loop, you can iterate over the ConcurrentBag and get build your final string in a safe environment.

Update based on comment
Comment:

System.Web.HttpContext.Current.Server.MapPath
used and HttpContext.Current is null
in Multi Thread loop.

The reason for this is that you are now on a different thread to the current HttpContext, therefore it can't answer any questions for you. You'll either have to pass in the context to the parallel task or the individual values from it. I don't know how dangerous that is in a parallel environment.

HttpContext myContext = HttpContext.Current;

In your parallel loop use myContext rather than HttpContext.Current.

I don't recommend this as the knowledge of the HttpContext in areas (like the data layer) sets up unnecessary coupling and made the application very difficult to maintain. To recommend a better solution would require pulling your application apart much more that is viable in a forum posting. However, for the moment it should get you moving again.

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