C#使用LINQ查詢操作符實(shí)例代碼(二)
相關(guān)閱讀
六、連表操作符
1、內(nèi)連接
1、使用 join 子句 根據(jù)特定的條件合并兩個(gè)數(shù)據(jù)源,但之前要獲得兩個(gè)要連接的列表。
業(yè)務(wù)說(shuō)明:返回1958到1965年間的車手冠軍和車隊(duì)冠軍信息,根據(jù)年份關(guān)聯(lián)
var racers = from r in Formula1.GetChampions()
from y in r.Years
select new
{
Year = y,
Name = r.FirstName + " " + r.LastName
};
var teams = from t in Formula1.GetContructorChampions()
from y in t.Years
select new
{
Year = y,
Name = t.Name
};
var racersAndTeams0 =
(from r in racers
join t in teams on r.Year equals t.Year
orderby t.Year
select new
{
Year = r.Year,
Racer = r.Name,
Team = t.Name
}).Take(10);方法語(yǔ)法:
var racersAndTeams = racers
.Join(teams, r => r.Year, t => t.Year, (r, t) => new { Year = r.Year, Racer = r.Name, Team = t.Name })
.OrderBy(p => p.Year).Take(10);結(jié)果:
Year Champion Constructor Title
1958: Mike Hawthorn Vanwall
1959: Jack Brabham Cooper
1960: Jack Brabham Cooper
1961: Phil Hill Ferrari
1962: Graham Hill BRM
1963: Jim Clark Lotus
1964: John Surtees Ferrari
1965: Jim Clark Lotus
1966: Jack Brabham Brabham
1967: Denny Hulme Brabham
2、或者合并成一個(gè)LINQ 查詢
var racersAndTeams =
(from r in
from r1 in Formula1.GetChampions()
from yr in r1.Years
select new
{
Year = yr,
Name = r1.FirstName + " " + r1.LastName
}
join t in
from t1 in Formula1.GetContructorChampions()
from yt in t1.Years
select new
{
Year = yt,
Name = t1.Name
}
on r.Year equals t.Year
orderby t.Year
select new
{
Year = r.Year,
Racer = r.Name,
Team = t.Name
}).Take(10);方法語(yǔ)法
var racersAndTeams0 = Formula1.GetChampions()
.SelectMany(m => m.Years, (m, y) => new { Racer = m, Year = y })
.Join(Formula1.GetContructorChampions()
.SelectMany(m => m.Years, (m, y) => new { Team = m, Year = y })
, m => m.Year, m1 => m1.Year
, (m, m1) => new
{
Year = m.Year,
Racer = m.Racer.FirstName + " " + m.Racer.LastName,
Team = m1.Team.Name
})
.OrderBy(m => m.Year).Take(10);2、左外連接(DefaultIfEmpty)
左外連接返回左邊序列中的全部元素,即使它們?cè)谟疫叺男蛄兄胁](méi)有匹配的元素。
左外連接用join子句和 DefaultIfEmpty 方法定義。 使用 DefaultIfEmpty 定義其右側(cè)的默認(rèn)值。
linq只支持左連接,如要右連接,將query和query1調(diào)換位置
業(yè)務(wù)說(shuō)明:如賽車手比車隊(duì)設(shè)立冠軍的年份要早,可能某個(gè)年份只有賽車手冠軍沒(méi)有車隊(duì)冠軍,這時(shí)候需要左連接查詢。
var racers = from r in Formula1.GetChampions()
from y in r.Years
select new
{
Year = y,
Name = r.FirstName + " " + r.LastName
};
var teams = from t in Formula1.GetContructorChampions()
from y in t.Years
select new
{
Year = y,
Name = t.Name
};
var racersAndTeams =
(from r in racers
join t in teams on r.Year equals t.Year into rt
from t in rt.DefaultIfEmpty()
orderby r.Year
select new
{
Year = r.Year,
Champion = r.Name,
Constructor = t == null ? "no constructor championship" : t.Name
}).Take(10);
foreach (var item in racersAndTeams)
{
Console.WriteLine("{0}: {1,-20} {2}", item.Year, item.Champion, item.Constructor);
}結(jié)果
1950: Nino Farina no constructor championship
1951: Juan Manuel Fangio no constructor championship
1952: Alberto Ascari no constructor championship
1953: Alberto Ascari no constructor championship
1954: Juan Manuel Fangio no constructor championship
1955: Juan Manuel Fangio no constructor championship
1956: Juan Manuel Fangio no constructor championship
1957: Juan Manuel Fangio no constructor championship
1958: Mike Hawthorn Vanwall
1959: Jack Brabham Cooper
3、組連接
左外連接使用了組連接和 into 子句。它有一部分與組連接相同,只不過(guò)組連接不適用 DefaultIfEmpty 方法。
使用組連接時(shí),基于鍵相等對(duì)兩個(gè)兩個(gè)獨(dú)立的序列的元素進(jìn)行關(guān)聯(lián)并對(duì)結(jié)果進(jìn)行分組。
常應(yīng)用于返回“主鍵對(duì)象-外鍵對(duì)象集合”形式的查詢。
業(yè)務(wù)說(shuō)明:返回1958到1965年間的車手冠軍和車隊(duì)冠軍信息,根據(jù)年份關(guān)聯(lián)并分組
注意:直接出現(xiàn)在join子句之后的into關(guān)鍵字會(huì)被翻譯為GroupJoin,而在select或group子句之后的into表示繼續(xù)一個(gè)查詢。
// 查詢表達(dá)式
var racersAndTeams =( from r in racers
join t in teams on r.Year equals t.Year into groupTeams
select new
{
Year = r.Year,
Racer = r.Name,
GroupTeams = groupTeams
}).Take(10);方法語(yǔ)法:
var racersAndTeams1 = racers
.GroupJoin(teams, r => r.Year, t => t.Year, (r, t) => new { Year = r.Year, Racer = r.Name, GroupTeams = t }
).Take(10);;
foreach (var item in racersAndTeams)
{
Console.WriteLine("{0}: {1,-20} {2}", item.Year, item.Racer, item.GroupTeams.Count());
}結(jié)果:
1950: Nino Farina 0
1952: Alberto Ascari 0
1953: Alberto Ascari 0
1951: Juan Manuel Fangio 0
1954: Juan Manuel Fangio 0
1955: Juan Manuel Fangio 0
1956: Juan Manuel Fangio 0
1957: Juan Manuel Fangio 0
1958: Mike Hawthorn 1
1961: Phil Hill 1
2、join…on…equals…支持多個(gè)鍵關(guān)聯(lián),可以使用匿名類型來(lái)對(duì)多個(gè)鍵值進(jìn)行Join,如下所示:
// 查詢表達(dá)式
var query17 = from r in racers
join r2 in teams on new { Name = r.Name.Substring(0, 1), Year = r.Year } equals new { Name = r2.Name.Substring(0, 1), Year = r2.Year } into yearResults
select new
{
Results = yearResults
};
foreach (var item in query17)
{
foreach (var info in item.Results)
{
Console.WriteLine(info.Name);
}
}
//McLaren七、集合操作
集合操作通過(guò)調(diào)用實(shí)體類的 GetHashCode() 和 Equals() 方法比較對(duì)象。 對(duì)于自定義比較,可以傳遞實(shí)現(xiàn) IEqualityComparer接口的對(duì)象。
- 1) Union:并集,返回兩個(gè)序列的并集,去掉重復(fù)元素。
- 2) Concat:連接,返回兩個(gè)序列的并集。
- 3) Intersect:交集,返回兩個(gè)序列中都有的元素,即交集。
- 4) Except:差集,返回只出現(xiàn)在一個(gè)序列中的元素,即差集。
業(yè)務(wù)說(shuō)明:獲取使用車型”Ferrari”和車型”Mclaren”都獲得過(guò)車手冠軍車手列表
void Main()
{
Func<string, IEnumerable<Racer>> racersByCar = car => from r in Formula1.GetChampions()
from c in r.Cars
where c == car
orderby r.LastName
select r;
foreach (var racer in racersByCar("Ferrari").Intersect(racersByCar("McLaren"), new RacerComparer()))
{
Console.WriteLine(racer);
}
}
public class RacerComparer : IEqualityComparer<Racer>
{
public bool Equals(Racer x, Racer y)
{
if (Object.ReferenceEquals(x, y)) return true;
return x != null && y != null && x.FirstName == y.FirstName && x.LastName == y.LastName;
}
public int GetHashCode(Racer obj)
{
int hashStudentId = obj.FirstName.GetHashCode();
int hashScore = obj.LastName.GetHashCode();
return hashStudentId ^ hashScore;
}
}結(jié)果:
Niki Lauda
- 5) Zip:通過(guò)使用指定的委托函數(shù)合并兩個(gè)序列,集合的總個(gè)數(shù)不變。
示例:合并html開(kāi)始標(biāo)簽和結(jié)束標(biāo)簽
var letters = new string[] { "A", "B", "C", "D", "E" };
var numbers = new int[] { 1, 2, 3 };
var q = letters.Zip(numbers, (l, n) => l + n.ToString());
foreach (var s in q)
Console.WriteLine(s);結(jié)果:
A1
B2
C3
- 6) SequenceEqual:判斷兩個(gè)序列是否相等,需要內(nèi)容及順序都相等。
示例:
int[] arr1 = { 1, 4, 7, 9 };
int[] arr2 = { 1, 7, 9, 4 };
Console.WriteLine("排序前 是否相等:{0}"
, arr1.SequenceEqual(arr2) ? "是" : "否"); // 否
Console.WriteLine();
Console.WriteLine("排序后 是否相等:{0}"
, arr1.SequenceEqual(arr2.OrderBy(k => k)) ? "是" : "否"); // 是八、分區(qū)操作符
擴(kuò)展方法 Take() 和 Skip() 等的分區(qū)操作可以用于分頁(yè)。
添加在查詢的“最后”,返回集合的一個(gè)子集。
1、Take():
從序列的開(kāi)頭返回指定數(shù)量的連續(xù)元素。
2、TakeWhile():
只要滿足指定的條件,就會(huì)返回序列的元素。
從第一個(gè)元素開(kāi)始, 讀取Starts小于40的人員列表,只要遇到大于40的元素就立即停止返回。
var racers = (from r in Formula1.GetChampions()
orderby r.Starts
select r
)
<strong>.TakeWhile(p </strong><strong>=> p.Starts < 40</strong><strong>);</strong>
foreach (var name in racers)
{
Console.WriteLine($"{name:A}");
}結(jié)果:
Alberto Ascari, Italy; starts: 32, wins: 10
Nino Farina, Italy; starts: 33, wins: 5
3、Skip():
跳過(guò)序列中指定數(shù)量的元素,然后返回剩余的元素。
業(yè)務(wù)說(shuō)明:將車手冠軍列表按每頁(yè)5個(gè)名字進(jìn)行分頁(yè)。
int pageSize = 5;
int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() / (double)pageSize);
for (int page = 0; page < numberPages; page++)
{
Console.WriteLine("Page {0}", page);
var racers = (
from r in Formula1.GetChampions()
orderby r.LastName
select r.FirstName + " " + r.LastName
)
.Skip(page * pageSize).Take(pageSize);
foreach (var name in racers)
{
Console.WriteLine(name);
}
}結(jié)果:
Page 0
Fernando Alonso
Mario Andretti
Alberto Ascari
Jack Brabham
Jim Clark
Page 1
Juan Manuel Fangio
Nino Farina
Emerson Fittipaldi
Mika Hakkinen
Mike Hawthorn
4、SkipWhile():
只要滿足指定的條件,就跳過(guò)序列中的元素,然后返回剩余元素。
九、聚合操作符
聚合操作符返回一個(gè)值。
1、LongCount:返回一個(gè) System.Int64,表示序列中的元素的總數(shù)量。
業(yè)務(wù)說(shuō)明:下面的Count 方法只返回獲得冠軍次數(shù)超過(guò)三次的賽車手,因?yàn)橥粋€(gè)查詢中需要使用同一個(gè)計(jì)數(shù)超過(guò)一次,所以使用let 子句定義了一個(gè)變量 numberYear.
var query = from r in Formula1.GetChampions()
let numberYears = r.Years.Count()
where numberYears >= 3
orderby numberYears descending, r.LastName
select new
{
Name = r.FirstName + " " + r.LastName,
TimesChampion = numberYears
};
foreach (var r in query)
{
Console.WriteLine("{0} {1}", r.Name, r.TimesChampion);
}
//Michael Schumacher 7
//Juan Manuel Fangio 5
//Alain Prost 4
//Jack Brabham 3
//Niki Lauda 3
//Nelson Piquet 3
//Ayrton Senna 3
//Jackie Stewart 32、Sum: 序列中的所有數(shù)字的和。
業(yè)務(wù)說(shuō)明:下面的Sum 方法用于計(jì)算一個(gè)國(guó)家贏得比賽的總次數(shù)。
首先根據(jù)國(guó)家對(duì)賽車手分組,再在新創(chuàng)建的匿名類型中,把Wins 屬性賦予某個(gè)國(guó)家贏得比賽的總次數(shù)。
var countries = (from c in
from r in Formula1.GetChampions()
group r by r.Country into c
select new
{
Country = c.Key,
Wins = (from r1 in c
select r1.Wins).Sum()
}
orderby c.Wins descending, c.Country
select c).Take(5);
foreach (var country in countries)
{
Console.WriteLine("{0} {1}", country.Country, country.Wins);
}
//UK 138
//Germany 91
//Brazil 78
//France 51
//Finland 403、Aggregate: 傳遞一個(gè) lambda 表達(dá)式,該表達(dá)式對(duì)所有的值進(jìn)行聚合。
業(yè)務(wù)說(shuō)明:Aggregate的
第一個(gè)參數(shù)是算法的種子,即初始值。(可選)
第二個(gè)參數(shù)是一個(gè)表達(dá)式,用來(lái)對(duì)每個(gè)元素進(jìn)行計(jì)算(委托第一個(gè)參數(shù)是累加變量,第二個(gè)參數(shù)當(dāng)前項(xiàng))。
第三個(gè)參數(shù)是一個(gè)表達(dá)式,用來(lái)對(duì)最終結(jié)果進(jìn)行數(shù)據(jù)轉(zhuǎn)換。
int[] numbers = { 1, 2, 3 };
int y = numbers.Aggregate((tol, n) => prod + n); // 1+2+3 = 6
int x = numbers.Aggregate(0, (tol, n) => tol + n); // 0+1+2+3 = 6
int z = numbers.Aggregate(0, (tol, n) => tol + n, r => r * 2);// (0+1+2+3)*2 = 12十、轉(zhuǎn)換操作符
查詢可以推遲到訪問(wèn)數(shù)據(jù)項(xiàng)時(shí)再執(zhí)行。在迭代中使用查詢時(shí),查詢會(huì)執(zhí)行。
而使用轉(zhuǎn)換操作符會(huì)立即執(zhí)行查詢,把查詢結(jié)果放在數(shù)組、列表或字典中。
LINQ本身支持四種不同的集合生成方式,包含生成數(shù)組的ToArray()、生成列表的ToList、生成字典集合的ToDictionary 以及生成Lookup<tkey,telement>類的ToLookup。
1) Cast:
將非泛型的 IEnumerable 集合元素轉(zhuǎn)換為指定的泛型類型,若類型轉(zhuǎn)換失敗則拋出異常。
如果需要在非類型化的集合上(如ArrayList)使用LINQ 查詢,就可以使用Cast 方法。
在下面的例子中,基于Object類型的ArrayList集合用Racer對(duì)象填充。
var list = new ArrayList(Formula1.GetChampions() as System.Collections.ICollection);
var query = from r in list.Cast()
where r.Country == "USA"
orderby r.Wins descending
select r;
foreach (var racer in query)
{
Console.WriteLine("{0:A}", racer);
}
//Mario Andretti, USA; starts: 128, wins: 12
//Phil Hill, USA; starts: 48, wins: 32) ToArray:
從 IEnumerable 創(chuàng)建一個(gè)數(shù)組。
3) ToList:
立即執(zhí)行查詢,從 IEnumerable 創(chuàng)建一個(gè) List。
4) ToDictionary:
根據(jù)指定的鍵選擇器函數(shù),從 IEnumerable 創(chuàng)建一個(gè) Dictionary<tkey,tvalue>。
將列表轉(zhuǎn)換為字典:
var spartans = new List<dynamic>
{
new {Opponent="UAB",Score="55-18"},
new {Opponent="Bowling Green",Score="55-18"},
new {Opponent="Pittsburgh",Score="55-18"},
new {Opponent="Notre Dame",Score="55-18"}
};
//字典是一種鍵值對(duì)的集合,ToDictionary 將一個(gè)IEnumerable<T>對(duì)象(比如LINQ查詢所返回的結(jié)果)
//轉(zhuǎn)換為一個(gè)IDictionary<Key,Value>對(duì)象。
IDictionary<string, dynamic> stats = spartans.ToDictionary(key => (string)key.Opponent);
Console.WriteLine("Spartans vs. {0} {1}", stats["Notre Dame"].Opponent, stats["Notre Dame"].Score);5) ToLookup:
根據(jù)指定的鍵選擇器函數(shù),從 IEnumerable 創(chuàng)建一個(gè) System.Linq.Lookup。
ToLookup使用比較復(fù)雜,Lookup類似于Dictionary,不過(guò),Dictionary每個(gè)鍵只對(duì)應(yīng)一個(gè)值,而Lookup則是1:n 的映射。
Lookup沒(méi)有公共構(gòu)造函數(shù),而且是不可變的。在創(chuàng)建Lookup之后,不能添加或刪除其中的元素或鍵。(可以將ToLookup 視為GroupBy與ToDictionary的功能合體)
業(yè)務(wù)說(shuō)明:將車手冠軍按其使用車型進(jìn)行分組,并顯示使用”williams”車型的車手名字。
ILookup<string, Racer> racers =
(from r in Formula1.GetChampions()
from c in r.Cars //使用復(fù)合的from 查詢
select new
{
Car = c,
Racer = r
}
).ToLookup(cr => cr.Car, cr => cr.Racer);
if (racers.Contains("Williams"))
{
foreach (var williamsRacer in racers["Williams"])
{
Console.WriteLine(williamsRacer);
}
}
//Alan Jones
//Keke Rosberg
//Nelson Piquet
//Nigel Mansell
//Alain Prost
//Damon Hill
//Jacques Villeneuve6) DefaultIfEmpty:
返回指定序列的元素;如果序列為空,則返回包含類型參數(shù)的默認(rèn)值的單一元素集合 。
var defaultArrCount = (new int[0]).DefaultIfEmpty().Count(); Console.WriteLine(defaultArrCount); //1
7) AsEnumerable:
返回類型為 IEnumerable 。用于處理LINQ to Entities操作遠(yuǎn)程數(shù)據(jù)源與本地集合的協(xié)作
十一、生成操作符
生成操作符返回一個(gè)新的集合。三個(gè)生成操作符不是擴(kuò)展方法,而是返回序列的正常靜態(tài)方法。
1) Empty:
生成一個(gè)具有指定類型參數(shù)的空序列 IEnumerable。
Empty() 方法返回一個(gè)不返回值的迭代器,用于需要一個(gè)集合的參數(shù),可以給參數(shù)傳遞空集合。
string[] names1 = { "Hartono, Tommy" };
string[] names2 = { "Adams, Terry", "Andersen, Henriette Thaulow", "Hedlund, Magnus", "Ito, Shu" };
string[] names3 = { "Solanki, Ajay", "Hoeing, Helge", "Andersen, Henriette Thaulow", "Potra, Cristina", "Iallo, Lucio" };
List<string[]> namesList = new List<string[]> { names1, names2, names3 };
IEnumerable<string> allNames = namesList.Aggregate(Enumerable.Empty<string>(), (current, next) => next.Length > 3 ? current.Union(next) : current);
foreach (string name in allNames)
{
Console.WriteLine(name);
}
//Adams, Terry
//Andersen, Henriette Thaulow
//Hedlund, Magnus
//Ito, Shu
//Solanki, Ajay
//Hoeing, Helge
//Potra, Cristina
//Iallo, Lucio2) Range:
生成指定范圍內(nèi)的整數(shù)的序列 IEnumerable。
如需要填充一二范圍的數(shù)字,此時(shí)就應(yīng)使用 Range() 方法。這個(gè)方法第一個(gè)參數(shù)作為起始值,把第二個(gè)參數(shù)作為要填充的項(xiàng)數(shù)。
var values = Enumerable.Range(1, 20);
foreach (var value in values)
{
Console.WriteLine(value);
}
// 結(jié)果 1 2 3 4 5 6 ...... 19 20Range() 方法不返回填充所定義值的集合,與其他方法一樣,推遲查詢,返回一個(gè) RangeEnumerator。其中用 yield return 語(yǔ)句,來(lái)遞增值。該結(jié)果也可以與其他擴(kuò)展方法一起用。
var values = Enumerable.Range(1, 5).Select(n => n * 3);
foreach (var value in values)
{
Console.WriteLine(value);
}
// 3 6 9 12 153) Repeat:
生成包含一個(gè)重復(fù)值的序列 IEnumerable。
Repeat() 方法 返回一個(gè)迭代器,把同一個(gè)值重復(fù)特定的次數(shù)。
IEnumerable<string> strings = Enumerable.Repeat("I like programming.", 3);
foreach (String str in strings)
{
Console.WriteLine(str);
}
//I like programming.
//I like programming.
//I like programming.十二、量詞操作符
如果元素序列滿足指定的條件,量詞操作符就返回布爾值。
1) Any:
確定序列是否包含任何元素;或確定序列中的任何元素是否都滿足條件。
//獲取是否存在姓為“Schumacher”的車手冠軍 var hasRacer_Schumacher = Formula1.GetChampions().Any(r => r.LastName == "Schumacher"); Console.WriteLine(hasRacer_Schumacher); //True
2) All:
確定序列中的所有元素是否滿足條件。
3) Contains:
確定序列是否包含指定的元素。
十三、元素操作符
這些元素操作符僅返回一個(gè)元素,不是IEnumerable。(默認(rèn)值:值類型默認(rèn)為0,引用類型默認(rèn)為null)
業(yè)務(wù)說(shuō)明:獲取冠軍數(shù)排名第三的車手冠軍
var Racer3 = Formula1.GetChampions()
.OrderByDescending(r => r.Wins)
.ElementAtOrDefault(2);
Console.WriteLine(Racer3);
//Ayrton Senna- 1) First:返回序列中的第一個(gè)元素;如果是空序列,此方法將引發(fā)異常。
- 2) FirstOrDefault:返回序列中的第一個(gè)元素;如果是空序列,則返回默認(rèn)值default(TSource)。
- 3) Last:返回序列的最后一個(gè)元素;如果是空序列,此方法將引發(fā)異常。
- 4) LastOrDefault:返回序列中的最后一個(gè)元素;如果是空序列,則返回默認(rèn)值default(TSource)。
- 5) Single:返回序列的唯一元素;如果是空序列或序列包含多個(gè)元素,此方法將引發(fā)異常。
- 6) SingleOrDefault:返回序列中的唯一元素;如果是空序列,則返回默認(rèn)值default(TSource);如果該序列包含多個(gè)元素,此方法將引發(fā)異常。
- 7) ElementAt:返回序列中指定索引處的元素,索引從0開(kāi)始;如果索引超出范圍,此方法將引發(fā)異常。
- 8) ElementAtOrDefault:返回序列中指定索引處的元素,索引從0開(kāi)始;如果索引超出范圍,則返回默認(rèn)值default(TSource)。
十四、并行查詢,并行Linq
AsParallel() 方法,擴(kuò)展 IEnumerable 接口,返回 ParallelQuery類,所以正常的集合類可以以平行方式查詢。
var query24 = from r in Formual.GetChampions().AsParallel() select r;
十五、分區(qū)器
AsParallel()方法不僅擴(kuò)展了 IEnumerable 接口,還擴(kuò)展了 Partitioner 類。通過(guò)它,可以影響創(chuàng)建的分區(qū)。
手動(dòng)創(chuàng)建一個(gè)分區(qū)器
var query25 = from r in Partitioner.Create (Formual.GetChampions(), true).AsParallel() select r;
十六、取消
.NET 提供一個(gè)標(biāo)準(zhǔn)方法,來(lái)取消長(zhǎng)時(shí)間運(yùn)行的任務(wù),也適用于并行Linq。
要取消長(zhǎng)時(shí)間運(yùn)行的查詢可以給查詢添加WithCancellation() 方法,并傳遞一個(gè) CancellactionToken令牌作為參數(shù)。
CancelllationToken令牌從CancellactionTokenSource類中創(chuàng)建。該查詢?cè)趩为?dú)的線程中運(yùn)行,在該線程中,捕獲一個(gè)OperationCanceledException類型的異常。如果取消了查詢就觸發(fā)這個(gè)異常。
在主線程中,調(diào)用CancellationTokenSource類的Cancel()方法可以取消任務(wù)。
CancellationTokenSource cts = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
try
{
var res = from r in Formual.GetChampions().AsParallel().WithCancellation(cts.Token) select r;
Console.WriteLine("query finished, sum:{0}", res);
}
catch (OperationCanceledException ex)
{
Console.WriteLine("canceled!");
Console.WriteLine(ex.Message);
}
});
string input = Console.ReadLine();
if (input.ToLower().Equals("y"))
{
cts.Cancel();
Console.WriteLine("canceled 2!");
}到此這篇關(guān)于C#使用LINQ查詢操作符的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#實(shí)現(xiàn)將json轉(zhuǎn)換為DataTable的方法
這篇文章主要介紹了C#實(shí)現(xiàn)將json轉(zhuǎn)換為DataTable的方法,涉及C#操作json及DataTable的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
C# XML與Json之間相互轉(zhuǎn)換實(shí)例詳解
這篇文章主要介紹了C# XML與Json之間相互轉(zhuǎn)換實(shí)例詳解,大家參考使用吧2013-11-11
C#使用帶like的sql語(yǔ)句時(shí)防sql注入的方法
這篇文章主要介紹了C#使用帶like的sql語(yǔ)句時(shí)防sql注入的方法,采用了一個(gè)比較簡(jiǎn)單的字符串過(guò)濾方法就可以有效提高sql語(yǔ)句的安全性,防止sql注入,需要的朋友可以參考下2014-09-09
C#自定義序列化ISerializable的實(shí)現(xiàn)方法
這篇文章主要介紹了C#自定義序列化ISerializable的實(shí)現(xiàn)方法,涉及C#序列化的操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
C#調(diào)用VB進(jìn)行簡(jiǎn)繁轉(zhuǎn)換的方法
這篇文章主要介紹了C#調(diào)用VB進(jìn)行簡(jiǎn)繁轉(zhuǎn)換的方法,通過(guò)調(diào)用VB的動(dòng)態(tài)鏈接庫(kù)實(shí)現(xiàn)繁簡(jiǎn)轉(zhuǎn)換的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-02-02
如何使用C#讀寫(xiě)鎖ReaderWriterLockSlim
這篇文章向大家介紹了讀寫(xiě)鎖ReaderWriterLockSlim,其優(yōu)點(diǎn)就是多個(gè)線程可以同時(shí)讀取該對(duì)象,要了解更多讀寫(xiě)鎖的知識(shí),仔細(xì)閱讀下文吧2015-07-07
Unity給物體添加多個(gè)Tag的實(shí)現(xiàn)
這篇文章主要介紹了Unity給物體添加多個(gè)Tag的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

