C#使用LINQ查询操作符实例代码(二)

目录
  • 六、连表操作符
    • 1、内连接
    • 2、左外连接(DefaultIfEmpty)
    • 3、组连接
  • 七、集合操作
  • 八、分区操作符
    • 1、Take():
    • 2、TakeWhile():
    • 3、Skip():
    • 4、SkipWhile():
  • 九、聚合操作符
    • 1、Count: 返回集合项数。     
    • 2、LongCount:返回一个 System.Int64,表示序列中的元素的总数量。
    • 3、Sum: 序列中的所有数字的和。
    • 4、Min: 返回集合中的最小值。
    • 5、Max: 返回集合中的最大值。
    • 6、Average: 返回集合中的平均值。
    • 7、Aggregate: 传递一个 lambda 表达式,该表达式对所有的值进行聚合。
  • 十、转换操作符
    • 1) Cast:
    • 2) ToArray:
    • 3) ToList:
    • 4) ToDictionary:
    • 5) ToLookup:
    • 6) DefaultIfEmpty:
    • 7) AsEnumerable:
  • 十一、生成操作符
    • 1) Empty:
    • 2) Range:
    • 3) Repeat:
  • 十二、量词操作符
    • 1) Any:
    • 2) All:
    • 3) Contains:
  • 十三、元素操作符
  • 十四、并行查询,并行Linq
  • 十五、分区器
  • 十六、取消

六、连表操作符

1、内连接

1、使用 join 子句 根据特定的条件合并两个数据源,但之前要获得两个要连接的列表。

业务说明:返回1958到1965年间的车手冠军和车队冠军信息,根据年份关联

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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);

方法语法:

?

1

2

3

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);

结果:

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、或者合并成一个LINQ 查询

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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);

方法语法

?

1

2

3

4

5

6

7

8

9

10

11

12

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)

左外连接返回左边序列中的全部元素,即使它们在右边的序列中并没有匹配的元素。

左外连接用join子句和 DefaultIfEmpty 方法定义。 使用 DefaultIfEmpty 定义其右侧的默认值。

linq只支持左连接,如要右连接,将query和query1调换位置

业务说明:如赛车手比车队设立冠军的年份要早,可能某个年份只有赛车手冠军没有车队冠军,这时候需要左连接查询。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

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);

}

结果

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 子句。它有一部分与组连接相同,只不过组连接不适用 DefaultIfEmpty 方法。

使用组连接时,基于键相等对两个两个独立的序列的元素进行关联并对结果进行分组。

常应用于返回“主键对象-外键对象集合”形式的查询。

业务说明:返回1958到1965年间的车手冠军和车队冠军信息,根据年份关联并分组

注意:直接出现在join子句之后的into关键字会被翻译为GroupJoin,而在select或group子句之后的into表示继续一个查询。

?

1

2

3

4

5

6

7

8

9

// 查询表达式

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);

方法语法:

?

1

2

3

4

5

6

7

8

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());

}

结果:

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…支持多个键关联,可以使用匿名类型来对多个键值进行Join,如下所示:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// 查询表达式

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

七、集合操作

集合操作通过调用实体类的 GetHashCode() 和 Equals() 方法比较对象。 对于自定义比较,可以传递实现 IEqualityComparer接口的对象。

业务说明:获取使用车型”Ferrari”和车型”Mclaren”都获得过车手冠军车手列表

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

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;

    }

}

结果:

Niki Lauda

  • 1) Union:并集,返回两个序列的并集,去掉重复元素。
  • 2) Concat:连接,返回两个序列的并集。
  • 3) Intersect:交集,返回两个序列中都有的元素,即交集。
  • 4) Except:差集,返回只出现在一个序列中的元素,即差集。

示例:合并html开始标签和结束标签

?

1

2

3

4

5

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);

结果:

A1 
B2 
C3

  • 5) Zip:通过使用指定的委托函数合并两个序列,集合的总个数不变。

示例:

?

1

2

3

4

5

6

7

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)) ? "是" : "否"); // 是

  • 6) SequenceEqual:判断两个序列是否相等,需要内容及顺序都相等。

八、分区操作符

扩展方法 Take() 和 Skip() 等的分区操作可以用于分页。

添加在查询的“最后”,返回集合的一个子集。

1、Take()

从序列的开头返回指定数量的连续元素。

2、TakeWhile()

只要满足指定的条件,就会返回序列的元素。

从第一个元素开始, 读取Starts小于40的人员列表,只要遇到大于40的元素就立即停止返回。

?

1

2

3

4

5

6

7

8

9

10

var racers = (from r in Formula1.GetChampions()

              orderby r.Starts

              select r

              )

              <strong>.TakeWhile(p </strong><strong>=&gt; p.Starts &lt; 40</strong><strong>);</strong>

foreach (var name in racers)

{

    Console.WriteLine($"{name:A}");

}

结果:

Alberto Ascari, Italy; starts: 32, wins: 10 
Nino Farina, Italy; starts: 33, wins: 5

3、Skip()

跳过序列中指定数量的元素,然后返回剩余的元素。

业务说明:将车手冠军列表按每页5个名字进行分页。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

int pageSize = 5;

int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() / (double)pageSize);

for (int page = 0; page &lt; 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);

    }

}

结果:

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():

只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素。

九、聚合操作符

聚合操作符返回一个值。

1、Count: 返回集合项数。     

2、LongCount:返回一个 System.Int64,表示序列中的元素的总数量。

业务说明:下面的Count 方法只返回获得冠军次数超过三次的赛车手,因为同一个查询中需要使用同一个计数超过一次,所以使用let 子句定义了一个变量 numberYear.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

var query = from r in Formula1.GetChampions()

            let numberYears = r.Years.Count()

            where numberYears &gt;= 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 3

3、Sum: 序列中的所有数字的和。

业务说明:下面的Sum 方法用于计算一个国家赢得比赛的总次数。

首先根据国家对赛车手分组,再在新创建的匿名类型中,把Wins 属性赋予某个国家赢得比赛的总次数。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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 40

4、Min: 返回集合中的最小值。

5、Max: 返回集合中的最大值。

6、Average: 返回集合中的平均值。

7、Aggregate: 传递一个 lambda 表达式,该表达式对所有的值进行聚合。

业务说明:Aggregate的 
第一个参数是算法的种子,即初始值。(可选) 
第二个参数是一个表达式,用来对每个元素进行计算(委托第一个参数是累加变量,第二个参数当前项)。 
第三个参数是一个表达式,用来对最终结果进行数据转换

?

1

2

3

4

int[] numbers = { 1, 2, 3 };

int y = numbers.Aggregate((tol, n) =&gt; prod + n); // 1+2+3 = 6

int x = numbers.Aggregate(0, (tol, n) =&gt; tol + n); // 0+1+2+3 = 6

int z = numbers.Aggregate(0, (tol, n) =&gt; tol + n, r =&gt; r * 2);// (0+1+2+3)*2 = 12

十、转换操作符

查询可以推迟到访问数据项时再执行。在迭代中使用查询时,查询会执行。

而使用转换操作符会立即执行查询,把查询结果放在数组、列表或字典中。

LINQ本身支持四种不同的集合生成方式,包含生成数组的ToArray()、生成列表的ToList、生成字典集合的ToDictionary 以及生成Lookup<tkey,telement>类的ToLookup

1) Cast:

将非泛型的 IEnumerable 集合元素转换为指定的泛型类型,若类型转换失败则抛出异常。 
如果需要在非类型化的集合上(如ArrayList)使用LINQ 查询,就可以使用Cast 方法。

在下面的例子中,基于Object类型的ArrayList集合用Racer对象填充。

?

1

2

3

4

5

6

7

8

9

10

11

12

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: 3

2) ToArray:

从 IEnumerable 创建一个数组。

3) ToList:

立即执行查询,从 IEnumerable 创建一个 List。

4) ToDictionary:

根据指定的键选择器函数,从 IEnumerable 创建一个 Dictionary<tkey,tvalue>。

将列表转换为字典:

?

1

2

3

4

5

6

7

8

9

10

11

var spartans = new List&lt;dynamic&gt;

        {

            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"}

        };

//字典是一种键值对的集合,ToDictionary 将一个IEnumerable&lt;T&gt;对象(比如LINQ查询所返回的结果)

//转换为一个IDictionary&lt;Key,Value&gt;对象。

IDictionary&lt;string, dynamic&gt; stats = spartans.ToDictionary(key =&gt; (string)key.Opponent);

Console.WriteLine("Spartans vs. {0} {1}", stats["Notre Dame"].Opponent, stats["Notre Dame"].Score);

5) ToLookup:

根据指定的键选择器函数,从 IEnumerable 创建一个 System.Linq.Lookup。 
ToLookup使用比较复杂,Lookup类似于Dictionary,不过,Dictionary每个键只对应一个值,而Lookup则是1:n 的映射。 
Lookup没有公共构造函数,而且是不可变的。在创建Lookup之后,不能添加或删除其中的元素或键。(可以将ToLookup 视为GroupBy与ToDictionary的功能合体) 
业务说明:将车手冠军按其使用车型进行分组,并显示使用”williams”车型的车手名字。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

ILookup&lt;string, Racer&gt; racers =

    (from r in Formula1.GetChampions()

     from c in r.Cars //使用复合的from 查询

     select new

     {

         Car = c,

         Racer = r

     }

     ).ToLookup(cr =&gt; cr.Car, cr =&gt; 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 Villeneuve

6) DefaultIfEmpty:

返回指定序列的元素;如果序列为空,则返回包含类型参数的默认值的单一元素集合 。   

?

1

2

3

var defaultArrCount = (new int[0]).DefaultIfEmpty().Count();

Console.WriteLine(defaultArrCount);

//1

7) AsEnumerable:

返回类型为 IEnumerable 。用于处理LINQ to Entities操作远程数据源与本地集合的协作

十一、生成操作符

生成操作符返回一个新的集合。三个生成操作符不是扩展方法,而是返回序列的正常静态方法。

1) Empty:

生成一个具有指定类型参数的空序列 IEnumerable。 
Empty() 方法返回一个不返回值的迭代器,用于需要一个集合的参数,可以给参数传递空集合。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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&lt;string[]&gt; namesList = new List&lt;string[]&gt; { names1, names2, names3 };

IEnumerable&lt;string&gt; allNames =  namesList.Aggregate(Enumerable.Empty&lt;string&gt;(), (current, next) =&gt; next.Length &gt; 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, Lucio

2) Range:

生成指定范围内的整数的序列 IEnumerable。 
如需要填充一二范围的数字,此时就应使用 Range() 方法。这个方法第一个参数作为起始值,把第二个参数作为要填充的项数

?

1

2

3

4

5

6

7

var values = Enumerable.Range(1, 20);

foreach (var value in values)

{

    Console.WriteLine(value);

}

// 结果 1 2 3 4 5 6 ......  19 20

Range() 方法不返回填充所定义值的集合,与其他方法一样,推迟查询,返回一个 RangeEnumerator。其中用 yield return 语句,来递增值。该结果也可以与其他扩展方法一起用。

?

1

2

3

4

5

6

7

var values = Enumerable.Range(1, 5).Select(n =&gt; n * 3);

foreach (var value in values)

{

     Console.WriteLine(value);

}

// 3 6 9 12 15

3) Repeat:

生成包含一个重复值的序列 IEnumerable。 
Repeat() 方法 返回一个迭代器,把同一个值重复特定的次数。

?

1

2

3

4

5

6

7

8

9

IEnumerable&lt;string&gt; 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:

确定序列是否包含任何元素;或确定序列中的任何元素是否都满足条件。

?

1

2

3

4

//获取是否存在姓为“Schumacher”的车手冠军

var hasRacer_Schumacher = Formula1.GetChampions().Any(r =&gt; r.LastName == "Schumacher");

Console.WriteLine(hasRacer_Schumacher);

//True

2) All:

确定序列中的所有元素是否满足条件。

3) Contains:

确定序列是否包含指定的元素。

十三、元素操作符

这些元素操作符仅返回一个元素,不是IEnumerable。(默认值:值类型默认为0,引用类型默认为null)

业务说明:获取冠军数排名第三的车手冠军

?

1

2

3

4

5

6

var Racer3 = Formula1.GetChampions()

    .OrderByDescending(r =&gt; r.Wins)

    .ElementAtOrDefault(2);

Console.WriteLine(Racer3);

//Ayrton Senna

  • 1) First:返回序列中的第一个元素;如果是空序列,此方法将引发异常。
  • 2) FirstOrDefault:返回序列中的第一个元素;如果是空序列,则返回默认值default(TSource)。
  • 3) Last:返回序列的最后一个元素;如果是空序列,此方法将引发异常。
  • 4) LastOrDefault:返回序列中的最后一个元素;如果是空序列,则返回默认值default(TSource)。
  • 5) Single:返回序列的唯一元素;如果是空序列或序列包含多个元素,此方法将引发异常。
  • 6) SingleOrDefault:返回序列中的唯一元素;如果是空序列,则返回默认值default(TSource);如果该序列包含多个元素,此方法将引发异常。
  • 7) ElementAt:返回序列中指定索引处的元素,索引从0开始;如果索引超出范围,此方法将引发异常。
  • 8) ElementAtOrDefault:返回序列中指定索引处的元素,索引从0开始;如果索引超出范围,则返回默认值default(TSource)。

十四、并行查询,并行Linq

AsParallel() 方法,扩展 IEnumerable 接口,返回 ParallelQuery类,所以正常的集合类可以以平行方式查询。

?

1

var query24 = from r in Formual.GetChampions().AsParallel() select r;

十五、分区器

AsParallel()方法不仅扩展了 IEnumerable 接口,还扩展了 Partitioner 类。通过它,可以影响创建的分区。

手动创建一个分区器

?

1

var query25 = from r in Partitioner.Create (Formual.GetChampions(), true).AsParallel() select r;

十六、取消

.NET 提供一个标准方法,来取消长时间运行的任务,也适用于并行Linq。

要取消长时间运行的查询可以给查询添加WithCancellation() 方法,并传递一个 CancellactionToken令牌作为参数。

CancelllationToken令牌从CancellactionTokenSource类中创建。该查询在单独的线程中运行,在该线程中,捕获一个OperationCanceledException类型的异常。如果取消了查询就触发这个异常。

在主线程中,调用CancellationTokenSource类的Cancel()方法可以取消任务。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

CancellationTokenSource cts = new CancellationTokenSource();

Task.Factory.StartNew(() =&gt;

{

    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!");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux NDK交叉编译rtmp 与 ffmpeg+rtmp交叉编译(v7a,v8a) 完成流程

最近在学RTMP,记录一下完成的编译流程 我是mac 电脑,但是mac上编译一直通过不了,后来才换到服务器上编译, 其实mac也能编译,只是最开始踩到坑里面了… 这里记录一下linux编译完整流程 环境: NDK: android-ndk-r17cFfmpeg: ffmpeg4.2.2 (高版本也可以编译)system: mac 1. …

【Python】Python 网络编程 ( Socket 套接字简介 | Socket 套接字使用步骤 | Socket 套接字服务端与客户端开发 )

文章目录 一、Socket 套接字简介1、Socket 套接字概念2、Socket 套接字类型3、Socket 套接字使用步骤4、Socket 套接字服务端与客户端 二、Socket 服务端与客户端开发1、服务端2、客户端3、执行结果 一、Socket 套接字简介 1、Socket 套接字概念 Socket 套接字 是一种 进程之间…

什么是 web3?

在百度搜索引擎输入 “Web3”、“大厂”。跳出来基本都是这样的标题. 以及如今的互联网行业 “哀鸿遍野”&#xff0c;不仅内卷&#xff0c;还裁员。然后掀起一阵风&#xff0c;猛吹 Web3 的好&#xff0c;数据回归用户……最后再 “威逼利诱” 一下&#xff0c;Web3 就是 20 年…

剑指 Offer 37. 序列化二叉树 / LeetCode297. 二叉树的序列化与反序列化(二叉树遍历(深度优先搜索))

题目&#xff1a; 链接&#xff1a;剑指 Offer 37. 序列化二叉树&#xff1b;LeetCode 297. 二叉树的序列化与反序列化 难度&#xff1a;困难 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0…

LViT:语言与视觉Transformer在医学图像分割

论文链接&#xff1a;https://arxiv.org/abs/2206.14718 代码链接&#xff1a;GitHub - HUANGLIZI/LViT: This repo is the official implementation of "LViT: Language meets Vision Transformer in Medical Image Segmentation" (IEEE Transactions on Medical I…

ubuntu 20.04添加双网卡后,访问外网不通

原因 在机器上插了一个智能网卡后&#xff0c;在netplan中设置了静态IP&#xff0c;如下&#xff1a; cat /etc/netplan/01-network-manager-all.yaml # Let NetworkManager manage all devices on this system network:version: 2renderer: NetworkManagerethernets:eth1:d…

Cloud Kernel SIG 月度动态:支持龙芯和申威架构,合入两个内存新特性

Cloud Kernel SIG&#xff08;Special Interest Group&#xff09;&#xff1a;支撑龙蜥内核版本的研发、发布和服务&#xff0c;提供生产可用的高性价比内核产品。 01 SIG 整体进展 Cloud Kernel 开始支持龙芯和申威架构。 合入两个内存新特性&#xff1a;MEMCG LRU LOCK 和…

MIPI D-PHY 2.1协议(学习笔记)

1~3 简介/术语/参考文档 这三章属于介绍性内容&#xff0c;包括缩略语等名词术语解释内容&#xff0c;不再赘述。 直接进入以下正文部分 4 D-PHY概述 D-PHY描述了一种Source同步、高速、低功耗、低成本的PHY&#xff0c;特别适用于移动应用。这个D-PHY规范主要是为了将相机…

Vue 中通用的 css 列表入场动画效果

css 代码 .gradientAnimation {animation-name: gradient;animation-duration: 0.85s;animation-fill-mode: forwards;opacity: 0; }/* 不带前缀的放到最后 */ keyframes gradient {0% {opacity: 0;transform: translate(-100px, 0px);}100% {opacity: 1;transform: translate…

【点选验证码】生成点选验证码图片--多进程

import os from concurrent.futures import ThreadPoolExecutor #定义了一个线程池 from multiprocessing import Pool #---------------------进程from tqdm import tqdm from PIL import Image, ImageDraw, ImageFont, ImageOps import shutil,os import numpy as np impor…

Redis基础

常用中间件Redis详解 一、Redis概述 1.2、NoSQL 1、什么是NoSQL Not Only SQL &#xff1a;不仅仅是sql&#xff0c;泛指非关系型数据库 。 NoSQL不依赖于业务逻辑方式存储&#xff0c;而以简单的key—value 模式存储。大大增加了扩展能力 2、NoSQL特点 方便扩展&#x…

Linux_CentOS_7.9部署Docker以及镜像加速配置等实操验证全过程手册

前言&#xff1a;实操之前大家应该熟悉一个新的名词DevOps 俗称开发即运维、新一代开发工程师&#xff08;Development和Operations的组合词&#xff09;是一组过程、方法与系统的统称&#xff0c;用于促进开发&#xff08;应用程序/软件工程&#xff09;、技术运营和质量保障&…

合并 K 个升序链表——力扣23

题目描述 法一 顺序合并 class Solution { public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2){ListNode* dummy new ListNode(-1); //创建一个新的头节点 ListNode *curdummy, *aPtr l1, *bPtr l2;while(aPtr && bPtr){if(aPtr->val < bPtr->…

随手笔记——记录SLAM下各种库提供的重要函数

随手笔记——记录SLAM下各种库提供的重要函数 说明明细1.SVD分解&#xff08;Eigen&#xff09;2.HXb求解&#xff08;Eigen&#xff09; 说明 记录常用库提供的类、方法等 明细 1.SVD分解&#xff08;Eigen&#xff09; // SVD on W Eigen::JacobiSVDEigen::Matrix3d svd(…

版本适配好帮手 Android SDK Upgrade Assistant / Android Studio Giraffe新功能

首先是新版本一顿下载↓&#xff1a; Download Android Studio & App Tools - Android Developers 在Tools中找到Android SDK Upgrade Assistant 可以在此直接查看SDK升级相关信息&#xff0c;不用跑到WEB端去查看了。 例如看一下之前经常要对老项目维护的android 12蓝牙…

go学习 6、方法

6、方法 面向对象编程&#xff08;OOP&#xff09;&#xff0c;封装、组合。 6.1 方法声明 在函数声明时&#xff0c;在其名字之前放上一个变量&#xff0c;即是一个方法。这个附加的参数会将该函数附加到这种类型上&#xff0c;即相当于为这种类型定义了一个独占的方法。 …

gitee中fork了其他仓库,如何在本地进行同步

GitHub 操作&#xff1a;同步 Fork 来的仓库&#xff08;上游仓库&#xff09;_sigmarising的博客-CSDN博客 1. 设置upstream 2. git pull --rebase 3. 然后再执行pull、push操作

神经数据库:用于使用 ChatGPT 构建专用 AI 代理的下一代上下文检索系统 — (第 2/3 部分)

书接上回理解构建LLM驱动的聊天机器人时的向量数据库检索的局限性 - &#xff08;第1/3部分&#xff09;_阿尔法旺旺的博客-CSDN博客 其中我们强调了&#xff08;1&#xff09;嵌入生成&#xff0c;然后&#xff08;2&#xff09;使用近似近邻&#xff08;ANN&#xff09;搜索…

网络层协议总览

网络层协议总览 IPARP&#xff08;地址解析协议&#xff09;ICMP&#xff08;网际控制报文协议&#xff09;路由选择协议NAT&#xff08;网络地址转换协议&#xff09; 网络层的主要协议包括IP、ARP、RARP、ICMP、IGMP以及各种路由选择协议等。 IP IP协议是TCP/IP协议簇中的核…

Linux解决 Failed to restart NetworkManager.service: Unit not found问题

解决“Failed to restart NetworkManager.service: Unit not found.”问题的步骤 如果你遇到了“Failed to restart NetworkManager.service: Unit not found.”的错误信息&#xff0c;不要担心&#xff01;这个问题很常见&#xff0c;并且很容易解决。下面是解决这个问题的步…