当前位置: 首页 > 编程语言 > C#

C#中是否存在异步正则表达式,它们对我的情况有帮助吗?

时间:2023-04-10 23:52:04 C#

C#中存在异步正则表达式,它们对我的情况有帮助吗?我的应用程序使用正则表达式并行搜索多个文件,等待Task.WhenAll(filePaths.Select(FindThings));在FindThings内部,它花费大部分时间进行正则表达式搜索,因为文件的大小可能有数百MB。staticasyncTaskFindThings(stringpath){stringfileContent=null;尝试使用(varreader=File.OpenText(path))fileContent=awaitreader.ReadToEndAsync();}catch(Exceptione){WriteLine(lineIndex,"{0}:错误{1}",文件名,e);返回;}varexitMatches=_exitExp.Matches(fileContent);foreach(在exitMatches中匹配退出){if(_taskDelay>0)awaitTask.Delay(_taskDelay);//[…]为什么这很重要我收到了很多回复,表明我没有解释为什么这很重要。以此类推示例程序(使用Nitro.Async库)例如:usingSystem;使用System.Collections.Generic;使用System.Linq;使用系统文本;使用System.Threading.Tasks;使用Nito.AsyncEx;namespaceScrap{classProgram{staticvoidMain(string[]args){AsyncContext.Run(()=>MainAsync(args));}staticasyncvoidMainAsync(string[]args){vartasks=newList();varasyncStart=DateTime.Now;tasks.Add(Task.WhenAll(Enumerable.Range(0,10).Select(i=>ShowIndexAsync(i,asyncStart))));varstart=DateTime.Now;tasks.Add(Task.WhenAll(Enumerable.Range(0,10).Select(i=>ShowIndex(i,start))));等待Task.WhenAll(任务);控制台.ReadLine();}staticasyncTaskShowIndexAsync(intindex,DateTimestart){Console.WriteLine("ShowIndexAsync:{0}({1})",index,DateTime.Now-开始);awaitTask.Delay(index*100);Console.WriteLine("!ShowIndexAsync:{0}({1})",index,DateTime.Now-开始);}staticTaskShowIndex(intindex,DateTimestart){returnTask.Factory.StartNew(()=>{Console.WriteLine("ShowIndex:{0}({1})",index,DateTime.Now-开始);Task.Delay(index*100).Wait();Console.WriteLine("!ShowIndex:{0}({1})",index,DateTime.Now-开始);});所以这将调用ShowIndexAsync10次,然后调用ShowIndex10次并等待它们完成ShowIndexAsync是“异步到核心”而ShowIndex不是,但它们都在任务上运行。这里的阻塞操作是Task.Delay,区别是一个等待那个任务,另一个.Wait()在任务内部。您希望第一个队列(ShowIndexAsync)先完成,但您错了。ShowIndexAsync:0(00:00:00.0060000)!ShowIndexAsync:0(00:00:00.0070000)ShowIndexAsync:1(00:00:00.0080000)ShowIndexAsync:2(00:00:00.0110000)ShowIndexAsync:3(00:00:0000.01)ShowIndexAsync:4(00:00:00.0120000)ShowIndexAsync:5(00:00:00.0130000)ShowIndexAsync:6(00:00:00.0130000)ShowIndexAsync:7(00:00:00.0140000)ShowIndexAsync:8(00:05000.01)ShowIndexAsync:9(00:00:00.0150000)ShowIndex:0(00:00:00.0020000)!ShowIndex:0(00:00:00.0020000)ShowIndex:1(00:00:00.0030000)!ShowIndex:1(00:00:00.1100000)ShowIndex:2(00:00:00.1100000)!ShowIndex:2(00:00:00.3200000)ShowIndex:3(00:00:00.3200000)!ShowIndex:3(00:00:00.6220000)ShowIndex:4(00:00:00.6220000)!ShowIndex:4(00:00:01.0280000)ShowIndex:5(00:00:01.0280000)!ShowIndex:5(00:00:01.5420000)ShowIndex:6(00:00:01.5420000)!ShowIndex:6(00:00:02.1500000)ShowIndex:7(00:00:02.1510000)!ShowIndex:7(00:00:02.8650000)ShowIndex:8(00:00:02.8650000)!ShowIndex:8(00:00:03.6660000)ShowIndex:9(00:00:03.6660000)!ShowIndex:9(00:00:04.5780000)!ShowIndexAsync:1(00:00:04.5950000)!ShowIndex(As00ShowIndex2:00:04.5960000)!ShowIndexAsync:3(00:00:04.5970000)!ShowIndexAsync:4(00:00:04.5970000)!ShowIndexAsync:5(00:00:04.5980000)!ShowIndexAsync:59(ShowIndexAsync:7(00:00:04.5990000)!ShowIndexAsync:8(00:00:04.6000000)!ShowIndexAsync:9(00:00:04.6010000)为什么会发生这种情况?任务调度程序只会“等待”将如此多的真实线程编译成协作式多任务状态机。如果你有一个不能等待的阻塞操作,在这个例子中是Task.Delay(...).Wait(),但在我的问题中,正则表达式匹配,它不会合作并让任务调度程序正确管理任务.如果我们将示例程序更改为:staticasyncvoidMainAsync(string[]args){varasyncStart=DateTime.Now;awaitTask.WhenAll(Enumerable.Range(0,10).Select(i=>ShowIndexAsync(i,asyncStart)));varstart=DateTime.Now;awaitTask.WhenAll(Enumerable.Range(0,10).Select(i=>ShowIndex(i,start)));控制台.ReadLine();然后我们的输出变成:ShowIndexAsync:0(00:00:00.0050000)!ShowIndexAsync:0(00:00:00.0050000)ShowIndexAsync:1(00:00:00.0060000)ShowIndexAsync:2(00:00:00.0080000)ShowIndex:3(00:00:00.00.0080000)00:00.0090000)ShowIndexAsync:4(00:00:00.0090000)ShowIndexAsync:5(00:00:00.0100000)ShowIndexAsync:6(00:00:00.0110000)ShowIndexAsync:7(08:00:00))Sh100:00.0120000)ShowIndexAsync:9(00:00:00.0120000)!ShowIndexAsync:1(00:00:00.1150000)!ShowIndexAsync:2(00:00:00.2180000)!ShowIndexAsync:3(00:00:00.31600)!ShowIndexAsync:4(00:00:00.4140000)!ShowIndexAsync:5(00:00:00.5190000)!ShowIndexAsync:6(00:00:00.6130000)!ShowIndexAsync:7(00:00:00.7190000)!ShowIndexAsync:8(00:00:00.8170000)!ShowIndexAsync:9(0??0:00:00.9170000)ShowIndex:0(00:00:00.00:显示(索引)x!00:00:00.0040000)ShowIndex:3(00:00:00.0060000)ShowIndex:4(00:00:00.0090000)ShowIndex:2(00:00:00.0100000)ShowIndex:1(00:00:00.0100000)5ShowIndex(00:00:00.0130000)ShowIndex:6(00:00:00.0130000)ShowIndex:7(00:00:00.0150000)ShowIndex:8(00:00:00.0180000)!ShowIndex:7(00:00:00.7660000)ShowIndex!6(00:00:00.7660000)ShowIndex:9(00:00:00.7660000)!ShowIndex:2(00:00:00.7660000)!ShowIndex:5(00:00:00.7660000)!ShowIndex:4(00:60:000.7)!ShowIndex:3(00:00:00.7660000)!ShowIndex:1(00:00:00.7660000)!ShowIndex:8(00:00:00.8210000)!ShowIndex:9(00:00:01.6700000)注意异步调用的方式结束时间均匀分布,但非异步代码不会阻塞任务调度程序,因为它不会像预期的那样创建额外的实际线程进行协作。我不希望它占用更少的CPU时间等,但我的目标是让FindThings在合作庄园中进行多任务处理,即它的“异步核心”。正则表达式搜索是一个CPU绑定操作,因此它们需要时间。您可以使用Task.Run将工作推送到后台线程,从而使您的UI保持响应,但这不会帮助它们更快。由于您的搜索已经并行化,因此您可以做更多的事情。您可以尝试使用异步文件读取来减少线程池中阻塞线程的数量,但它可能不会产生巨大影响。您当前的代码正在调用ReadToEndAsync但它需要打开文件以进行异步访问(即使用FileStream构造函数并通过为isAsync参数传递true或为options参数传递FileOptions.Asynchronous来显式请求异步文件句柄)。您有一个包含大量文本和多个可能匹配项的大文件。一种可能的解决方案是将其偷偷放入5-10个迷你文件中。所以拿你的文本文件(1000行)并使用StreamReader创建5个迷你文件(200行)。使用不同的线程在所有迷你文件上运行您的正则表达式。我想知道这是否会减少运行时间。C#学习教程就是这些:C#中是否存在异步正则表达式,它们对我的情况有帮助吗?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: