C# 并行循环问题
当此代码运行时,向我显示此错误:“对象引用未设置到对象的实例” 第一行发生错误=> 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的异常可能表明其他事情。哪个值实际上是
null
?你不说。我可以看到这段代码存在一些问题。
您不能依赖于循环的顺序,但在整个并行代码中都有
temp +=
(依次将字符串添加到现有字符串,然后将该字符串分配回原始变量)。温度在并行循环之外设置。这是非常危险的。滥用共享状态/数据/资源是多线程代码中最常见的错误之一。temp 可能会不按顺序添加值。多个内容将同时添加到 temp 中,因此 temp 可能最终会丢失信息,因为 temp 被多个线程覆盖。
_Filings
来自哪里?它是什么?您可能想在循环内创建一个新的temp 添加到
temp
string
并在其中添加所有内容,将最终的ConcurrentBag (您在循环外部创建的)在每次迭代中。然后,在并行循环之外,您可以迭代
ConcurrentBag
并在安全的环境中构建最终字符串。根据评论更新
评论:
原因是您现在位于与当前 HttpContext 不同的线程上,因此它无法为您回答任何问题。您必须将上下文传递给并行任务或其中的各个值。我不知道这在并行环境中有多危险。
在并行循环中使用
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 finaltemp
to aConcurrentBag
(which you create outside the loop) in each iteration. Afterwards, outside of the parallel loop, you can iterate over theConcurrentBag
and get build your final string in a safe environment.Update based on comment
Comment:
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.
In your parallel loop use
myContext
rather thanHttpContext.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.