最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在Parallel中使用DbSet.Add()發(fā)現(xiàn)的一系列多線程問題和解決思路詳解

 更新時間:2016年11月14日 15:29:11   作者:balahoho  
這篇文章主要介紹了在Parallel中使用DbSet.Add()發(fā)現(xiàn)的一系列多線程問題和解決過程的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

發(fā)現(xiàn)問題

需求很簡單,大致就是要批量往數(shù)據(jù)庫寫數(shù)據(jù),于是打算用Parallel并行的方式寫入,希望能利用計算機多核特性加快程序執(zhí)行速度。想的很美好,于是快速擼了類似下面的一串代碼:

using (var db = new SmsEntities())
{
Parallel.For(0, 1000, (i) =>
{
db.MemberCard.Add(new MemberCard()
{
CardNo = "NO_" + i.ToString(),
Banlance = 0,
CreateTime = DateTime.Now,
Name = "Test_" + i.ToString(),
Status = 1
});
});
db.SaveChanges();
}

可意外的是竟然無情的報錯了:

奇葩的是當(dāng)我再次刷新的時候異常又不一樣了,于是連著刷新好多次,總結(jié)出現(xiàn)過的異常有下面這些:

1、 未將對象引用設(shè)置到對象的實例。

2、 已添加了具有相同鍵的項。

3、 集合已修改;可能無法執(zhí)行枚舉操作。

4、 一個 EdmType 不能多次映射到 CLR 類。EdmType“SmsModel.MemberCard”映射了一次以上。

其中1和2是出現(xiàn)最多的,而且所有異常都是出現(xiàn)在Add的時候,各種吃瓜表情~沒辦法,接著一一斷點調(diào)試,還是沒找出原因,出于進度考慮,換成了另一種方案,也就是用DbSet的AddRange方法。先在Parallel中累加出一個實體List,然后一次性添加到DbSet中,代碼演變?yōu)?

List<MemberCard> list = new List<MemberCard>();
using (var db = new SmsEntities())
{
var result = Parallel.For(0, 1000, (i) =>
{
list.Add(new MemberCard()
{
CardNo = "NO_" + i.ToString(),
Banlance = 0,
CreateTime = DateTime.Now,
Name = "Test_" + i.ToString(),
Status = 1
});
});
if (result.IsCompleted)
{
db.MemberCard.AddRange(list);
db.SaveChanges();
}
}

然后編譯、測試,沒問題,就先放著了。

分析問題

第二天到公司心里還在糾結(jié)這個問題,于是打開頁面輸入生成的數(shù)據(jù)量1000(真實項目中的循環(huán)次數(shù)是手動輸入的),點按鈕提交,嗯,又吃瓜般的異常了…:

心想昨天測試都好好的?。ㄆ鋵嵶蛱燧斎氲氖?0,心虛臉...),沒辦法,上斷點吧,一看嚇一跳:

明明循環(huán)1000次,結(jié)果只有971條數(shù)據(jù),而且里面還有為null的,經(jīng)過多次調(diào)試發(fā)現(xiàn)這是一個隨機現(xiàn)象,Count是隨機的null也是隨機的,有時出現(xiàn)有時沒有,初步判斷這是一個在多線程情況下引發(fā)的一個資源調(diào)配異常。So,上MSDN看了一下List的介紹,最后面“線程安全”寫著:

一切貌似都清楚了,于是打算驗證一下結(jié)果,加上了鎖,測試結(jié)果為:

list里面也沒有再出現(xiàn)null了,確認是因為多線程安全引起的異常。于是想起昨天那個問題是否也是同樣的問題,再上MSDN搜了一下DbContext類和DbSet類,都是這樣說的:

接著就給dbcontext上了鎖,測試,這次總算如我所料,完美運行。但是不解的是最初那幾個異常是如何產(chǎn)生的,List中雖然數(shù)量不夠也存在為null的對象,但是并沒有直接爆出異?!,F(xiàn)在只知道是線程問題,再詳細的也搞不清楚,有知道的大神還麻煩指點一下。

尋找解決方案并驗證結(jié)論

也想過用Partitioner分區(qū)來做,但是仔細一想,雖然分區(qū)內(nèi)部是單線程,但是區(qū)與區(qū)之間還是多線程的,如果分的太細也就失去了Parallel的意義,只得另尋出路。還好Framework為我們也提供了一些線程安全的泛型集合(比如ConcurrentBag、ConcurrentQueue等),不過其本質(zhì)還是用了鎖,于是就綜合做了一下單線程list、多線程list加鎖、多線程ConcurrentBag、多線程ConcurrentQueue的性能對比,結(jié)果如下:

循環(huán)1000次時:

循環(huán)10000次時:

循環(huán)100000次時:

得出結(jié)論就是,在執(zhí)行次數(shù)超大時用線程安全類型會更慢,在執(zhí)行次數(shù)較少時線程安全類型也沒什么優(yōu)勢。

解決問題

最后在經(jīng)過仔細測試驗證和考慮項目實際需求(幾乎不可能一次10000)后,去繁從簡,回歸原始,用最簡單直白的寫法單線程循環(huán)來完成。雖然一番折騰下來還是回到最初,但是這過程中讓我發(fā)現(xiàn)了意料之外問題,然后找到了原因,然后測試驗證,最終得到了最優(yōu)解決方案。還是那句話,填完坑,你就比之前更強大了!

相關(guān)文章

  • 關(guān)于ASP網(wǎng)頁無法打開的解決方案

    關(guān)于ASP網(wǎng)頁無法打開的解決方案

    asp網(wǎng)頁實際上就是動態(tài)網(wǎng)頁,是在服務(wù)端執(zhí)行和解析的。有時也很奇怪,經(jīng)常遇到asp網(wǎng)頁無法打開的情況,下面小編給大家整理些關(guān)于asp網(wǎng)頁無法打開的解決方案,需要的朋友可以參考下
    2015-08-08
  • Unity實現(xiàn)圖片水印生成

    Unity實現(xiàn)圖片水印生成

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)圖片水印生成,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • ASP.NET C#中Application的用法教程

    ASP.NET C#中Application的用法教程

    這篇文章主要給大家介紹了關(guān)于ASP.NET C#中Application的用法,在介紹Application的用法之前,先給大家介紹了Session的用法供大家參考學(xué)習(xí),文中介紹的非常詳細,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-05-05
  • C#中數(shù)組初始化與數(shù)組元素復(fù)制的方法

    C#中數(shù)組初始化與數(shù)組元素復(fù)制的方法

    這篇文章主要介紹了C#中數(shù)組初始化與數(shù)組元素復(fù)制的方法,涉及C#中數(shù)組的創(chuàng)建、初始化及使用Array.Copy方法復(fù)制數(shù)組元素的技巧,需要的朋友可以參考下
    2015-04-04
  • 漢字轉(zhuǎn)拼音縮寫示例代碼(Silverlight和.NET 將漢字轉(zhuǎn)換成為拼音)

    漢字轉(zhuǎn)拼音縮寫示例代碼(Silverlight和.NET 將漢字轉(zhuǎn)換成為拼音)

    本篇文章主要介紹了漢字轉(zhuǎn)拼音縮寫示例代碼(Silverlight和.NET 將漢字轉(zhuǎn)換成為拼音) 需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • C# List 并發(fā)丟數(shù)據(jù)問題原因及解決方案

    C# List 并發(fā)丟數(shù)據(jù)問題原因及解決方案

    這篇文章主要介紹了C# List 并發(fā)丟數(shù)據(jù)問題原因及解決方案,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-02-02
  • C#中使用反射遍歷一個對象屬性及值的小技巧

    C#中使用反射遍歷一個對象屬性及值的小技巧

    這篇文章主要介紹了C#中使用反射遍歷一個對象屬性及值的小技巧,這在很時候應(yīng)該都非常有用,本文直接給出實例代碼,需要的朋友可以參考下
    2015-07-07
  • c#后臺線程訪問前臺控件并顯示信息示例

    c#后臺線程訪問前臺控件并顯示信息示例

    這篇文章主要介紹了c#后臺線程訪問前臺控件并顯示信息示例,需要的朋友可以參考下
    2014-03-03
  • C#實現(xiàn)并查集的使用示例

    C#實現(xiàn)并查集的使用示例

    并查集是一種用于處理一些不相交集合的合并及查詢問題的數(shù)據(jù)結(jié)構(gòu),具有高效、簡潔、易用的特點,本文主要介紹了C#實現(xiàn)并查集的使用示例,感興趣的可以了解一下
    2023-11-11
  • C#從XmlDocument提取完整字符串的方法

    C#從XmlDocument提取完整字符串的方法

    文章介紹了兩種生成格式化XML字符串的方法,方法一使用`XmlDocument`的`OuterXml`屬性,但輸出的XML字符串不帶格式,可讀性差,方法二利用`XmlWriterSettings`控制格式,并通過`MemoryStream`作為輸出流,可以自定義編碼,如UTF-8,感興趣的朋友跟隨小編一起看看吧
    2025-02-02

最新評論

阳信县| 博客| 额尔古纳市| 西乌珠穆沁旗| 泽普县| 新乡县| 门源| 甘德县| 如皋市| 广水市| 大悟县| 招远市| 金溪县| 长沙市| 孙吴县| 逊克县| 金华市| 县级市| 进贤县| 宁安市| 乐陵市| 海安县| 陵水| 布尔津县| 包头市| 且末县| 泾川县| 秭归县| 团风县| 庆城县| 昌乐县| 云南省| 无棣县| 志丹县| 嘉禾县| 佛教| 沈阳市| 花垣县| 栾城县| 晋州市| 兰溪市|