当前位置: 首页 > news >正文

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

相关文章:

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

目录 六、连表操作符 1、内连接2、左外连接(DefaultIfEmpty)3、组连接七、集合操作 八、分区操作符 1、Take()&#xff1a;2、TakeWhile()&#xff1a;3、Skip()&#xff1a;4、SkipWhile()&#xff1a;九、聚合操作符 1、Count&#xff1a; 返回集合项数。 2、LongCount&…...

jenkinsfile小试牛刀

序 本文主要演示一下如何用jenkinsfile来编译java服务 安装jenkins 这里使用docker来安装jenkins docker run --name jenkins-docker \ --volume $HOME/jenkins_home:/var/jenkins_home \ -p 8080:8080 jenkins/jenkins:2.416之后访问http://${yourip}:8080&#xff0c;然后…...

C++ xmake构建

文章目录 一、xmake.lua二、xmake常用语句 一、xmake.lua --xmake.luaset_project("XXX")add_rules("mode.debug", "mode.release") set_config("arch", "x64")if is_plat("windows") then -- the release modei…...

推荐带500创作模型的付费创作V2.1.0独立版系统源码

ChatGPT 付费创作系统 V2.1.0 提供最新的对应版本小程序端&#xff0c;上一版本增加了 PC 端绘画功能&#xff0c; 绘画功能采用其他绘画接口 – 意间 AI&#xff0c;本版新增了百度文心一言接口。 后台一些小细节的优化及一些小 BUG 的处理&#xff0c;前端进行了些小细节优…...

wps图表怎么改横纵坐标,MLP 多层感知器和CNN卷积神经网络区别

目录 wps表格横纵坐标轴怎么设置&#xff1f; MLP (Multilayer Perceptron) 多层感知器 CNN (Convolutional Neural Network) 卷积神经网络 多层感知器MLP&#xff0c;全连接网络&#xff0c;DNN三者的关系 wps表格横纵坐标轴怎么设置&#xff1f; 1、打开表格点击图的右侧…...

rdb和aof

RDB持久化&#xff1a;原理是将Redis在内存中的数据库记录定时dump到磁盘上的RDB持久化AOF持久化&#xff1a;原理是将Redis的操作日志以追加的方式写入文件 rdb&#xff1a; 开启方式&#xff1a;客户端可以通过向Redis服务器发送save或bgsave命令让服务器生成rdb文件&#…...

TCP网络通信编程之网络上传文件

【图片】 【思路解析】 【客户端代码】 import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException;/*** ProjectName: Study* FileName: TCPFileUploadClient* author:HWJ* Data: 2023/7/29 18:44*/ public class TCPFil…...

Java中对Redis的常用操作

目录 数据类型五种常用数据类型介绍各种数据类型特点 常用命令字符串操作命令哈希操作命令列表操作命令集合操作命令有序集合操作命令通用命令 在Java中操作RedisRedis的Java客户端Spring Data Redis使用方式介绍环境搭建配置Redis数据源编写配置类&#xff0c;创建RedisTempla…...

链路追踪设计

...

Golang之路---02 基础语法——常量 (包括特殊常量iota)

常量 //显式类型定义const a string "test" //隐式类型定义const b 20 //多个常量定义 const(c "test2"d 2.3e 27)iota iota是Golang语言的常量计数器&#xff0c;只能在常量表达式中使用 iota在const关键字出现时将被重置为0&#xff0c;const中每新…...

Pytest学习教程_装饰器(二)

前言 pytest装饰器是在使用 pytest 测试框架时用于扩展测试功能的特殊注解或修饰符。使用装饰器可以为测试函数提供额外的功能或行为。   以下是 pytest 装饰器的一些常见用法和用途&#xff1a; 装饰器作用pytest.fixture用于定义测试用例的前置条件和后置操作。可以创建可重…...

redis的如何使用

1、redis的使用 1.1windows安装 安装包下载地址&#xff1a;Releases dmajkic/redis GitHub 1.2 redis中常使用的几个文件 1.3 redis中运行 双击redis-server&#xff0c;既可以运行。 1.4使用redis客户单来连接redis 1.5redis的常用指标 redis-serve 服务端,端口号&am…...

MyBatis(二)

文章目录 一.MyBatis的模式开发1.1 定义数据表和实体类1.2 配置数据源和MyBatis1.3 编写Mapper接口和增加xxxMapper.xml1.4 测试我们功能的是否实现. 二. Mybatis的增删查改操作2.1 单表查询2.2 多表查询三.动态SQL的实现3.1 什么是动态SQL3.2 动态SQL的使用if标签的使用trim标…...

【【51单片机AD转换模块】】

代码是简单的&#xff0c;板子是坏的&#xff0c;电阻是识别不出来的 main.c #include <REGX52.H> #include "delay.h" #include "LCD1602.h" #include "XPT2046.h"unsigned int ADValue;void main(void) {LCD_Init();LCD_ShowString(1,1…...

Longest Divisors Interval(cf)

题意&#xff1a;给定一个正整数n&#xff0c;求正整数的区间[l&#xff0c;r]的最大大小&#xff0c;使得对于区间中的每个i&#xff08;即l≤i≤r&#xff09;&#xff0c;n是i的倍数。给定两个整数l≤r&#xff0c;区间[l&#xff0c;r]的大小为r−l1&#xff08;即&#xf…...

配置文件、request对象请求方法、Django连接MySQL、Django中的ORM、ORM增删改查字段、ORM增删改查数据

一、配置文件的介绍 1.注册应用的 INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,app01.apps.App01Config, ]################中间件###############…...

CTF学习路线指南(附刷题练习网址)

前言&#xff1a; PWN,Reverse&#xff1a;偏重对汇编&#xff0c;逆向的理解&#xff1b; Gypto&#xff1a;偏重对数学&#xff0c;算法的深入学习&#xff1b; Web&#xff1a;偏重对技巧沉淀&#xff0c;快速搜索能力的挑战&#xff1b; Mic&#xff1a;则更为复杂&…...

【Rust 基础篇】Rust默认泛型参数:简化泛型使用

导言 Rust是一种以安全性和高效性著称的系统级编程语言&#xff0c;其设计哲学是在不损失性能的前提下&#xff0c;保障代码的内存安全和线程安全。在Rust中&#xff0c;泛型是一种非常重要的特性&#xff0c;它允许我们编写一种可以在多种数据类型上进行抽象的代码。然而&…...

从源码分析Handler面试问题

Handler 老生常谈的问题了&#xff0c;非常建议看一下Handler 的源码。刚入行的时候&#xff0c;大佬们就说 阅读源码 是进步很快的方式。 Handler的基本原理 Handler 的 重要组成部分 Message 消息MessageQueue 消息队列Lopper 负责处理MessageQueue中的消息 消息是如何添加…...

shell编程 变量作用域

变量 变量赋值不用$&#xff0c;访问值时用$,赋值时两边不留空格&#xff0c;双引号括起来的变量被值替换{}标记变量开始和结束,变量名区分大小写&#xff0c;所有bash变量的值变量不区分类型&#xff0c;统一为字符串 变量类型 环境变量&#xff0c;子进程可以继承父进程环境…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...