C# 异步搜索请求

C# 异步搜索请求,c#,asynchronous,linqpad,C#,Asynchronous,Linqpad,我已经有一年没有编码了,我需要LinqPad的帮助。我需要运行多个搜索查询以从数据库中获取数据 比如说我需要跑步 void DeepSearch(string input) { Orders.Where(y => y.OrderReference.Contains(input)).Dump(); Invoice.Where(y => y.InvoiceReference.Contains(input)).Dump(); Clients.Where(y =>

我已经有一年没有编码了,我需要LinqPad的帮助。我需要运行多个搜索查询以从数据库中获取数据

比如说我需要跑步

void DeepSearch(string input)
{
    Orders.Where(y => y.OrderReference.Contains(input)).Dump();
    Invoice.Where(y => y.InvoiceReference.Contains(input)).Dump();
    Clients.Where(y => y.Name.Contains(input)).Dump();
}
为了提高性能,我想同时启动这3个查询,并在得到结果后立即转储。我不在乎订单

我可以添加异步吗

async void DeepSearch(string input)
{
    Orders.Where(y => y.OrderReference.Contains(input)).Dump();
    Invoice.Where(y => y.InvoiceReference.Contains(input)).Dump();
    Clients.Where(y => y.Name.Contains(input)).Dump();
}
不,你不能;“async”与“parallel”不同,即使是:数据源需要(分别)设计为异步和/或并行。我猜这里的
订单
发票
客户端
都是通过共享数据库连接(可能使用EF)的LINQ提供程序,在这种情况下:ADO.NET中的数据库连接不是为并发/并行而设计的。此外,LINQ不直接公开异步操作,但:EF确实对异步执行做出了一些让步-如果您使用Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListSync()等方法,这意味着:使用Microsoft.EntityFrameworkCore添加
到文件的顶部,并使用
wait source.Where(…).ToListAsync()

然而:

  • 异步而不并行并不能提高直接观察到的性能;它只是意味着在等待DB时,您没有占用线程(有限的资源),允许释放线程并做比等待更有趣的事情
  • 并发是复杂的,需要单独的独立连接(etc)或为并发而设计的连接
不行;“异步”与“并行”不同,即使是:数据源需要(分别)设计为异步和/或并行。我猜,
订单
发票
客户端
这里是通过共享数据库连接(可能使用EF)的LINQ提供程序,在这种情况下:ADO.NET中的数据库连接不是为并发/并行而设计的。此外,LINQ不直接公开异步操作,但:EF确实对异步执行做出了一些让步-如果您使用Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListSync(),这只是意味着:使用Microsoft.EntityFrameworkCore添加
到文件的顶部,并使用
wait source.Where(…).ToListAsync()

然而:

  • 异步而不并行并不能提高直接观察到的性能;它只是意味着在等待DB时,您没有占用线程(有限的资源),允许释放线程并做比等待更有趣的事情
  • 并发是复杂的,需要单独的独立连接(etc)或为并发而设计的连接

如果您为每个并行操作实例化一个单独的数据上下文,您当然可以并行运行查询。(这是必需的,因为数据上下文不是线程安全的,无论是LINQ to SQL还是EF Core)

LINQPad自动生成的数据上下文称为
TypedDataContext
,因此LINQPad中的代码如下所示:

Task.Run(() => new TypedDataContext().Orders.Where(y => y.OrderReference.Contains(input)Dump());
Task.Run(() => new TypedDataContext().Invoices.Where(y => y.InvoiceReference.Contains(input)).Dump());
Task.Run(() => new TypedDataContext().Clients.Where(y => y.Name.Contains(input).Dump());
如果将任务分配给变量,则可以等待它们(或使用
Task.whalll
等待它们全部)


根据您使用的是LINQ to SQL还是EF Core,实例化数据上下文也会带来成本,因此您可能希望在同一线程上的后续操作中重复使用同一类型的DDataContext。

如果您为每个并行操作实例化单独的数据上下文,您当然可以并行运行查询。(这是必需的,因为数据上下文不是线程安全的,无论是LINQ到SQL还是EF核心)

LINQPad自动生成的数据上下文称为
TypedDataContext
,因此LINQPad中的代码如下所示:

Task.Run(() => new TypedDataContext().Orders.Where(y => y.OrderReference.Contains(input)Dump());
Task.Run(() => new TypedDataContext().Invoices.Where(y => y.InvoiceReference.Contains(input)).Dump());
Task.Run(() => new TypedDataContext().Clients.Where(y => y.Name.Contains(input).Dump());
如果将任务分配给变量,则可以等待它们(或使用
Task.whalll
等待它们全部)


根据您使用的是LINQ to SQL还是EF Core,实例化数据上下文也会带来成本,因此您可能希望在同一线程上的后续操作中重复使用同一类型的DDataContext。

可能使用EF。。。Correct@TheodorZoulias是的,你说得对-将编辑(CPU当然会在网络上进行冷等待,但仍然占用线程,这很昂贵)可能使用EF。。。Correct@TheodorZoulias是的,你说得对-将进行编辑(CPU当然会在网络上进行冷等待,但仍然会占用线程,这很昂贵)