我正在尝试编写一种读取 pdf 每一页的方法,但由于通过 api 读取每一页需要花费大量时间,而且我正在查看数百页长的 pdf,因此我想将异步读取每个页面,然后在准备好时返回结果,因此一次读取多个页面。
我使用 Task.Run 对任务进行“排队”,我希望看到调试日志不按顺序打印页面,但它们只按顺序执行,所以我认为它们是同步运行的。有什么想法吗?
var tasks = new List<Task>();
foreach (Page page in _pdfDoc.GetPages()) {
var task = Task.Run(() => {
//tried adding await Task.Yield() here, doesn't work
Debug.WriteLine("searching page " + page.Number);
if (page.Text.Contains(query)) {
pagesWithQuery.Add(page.Number);
}
howManySearched += 1;
Dispatcher.UIThread.InvokeAsync(() => {
searchProgress.Value = howManySearched;
});
return Task.CompletedTask;
});
tasks.Add(task);
// await task; <== does nothing??
}
// await Task.WhenAll(tasks); <== also nothing
我使用
“排队”任务,我希望看到调试日志不按顺序打印页面,但它们只按顺序执行,所以我认为它们是同步运行的。Task.Run
您没有足够的数据来支持这个假设。您仅记录每个
Task
: 的开头
Task task = Task.Run(() =>
{
Debug.WriteLine("searching page " + page.Number);
...但你不知道
Task
何时完成。通过执行以下操作,您可以更好地了解代码实现的并发级别:
object locker = new();
int concurrencyCounter = 0;
int maxConcurrency = 0;
Task task = Task.Run(() =>
{
Debug.WriteLine("searching page " + page.Number);
int concurrency = Interlocked.Increment(ref concurrencyCounter);
lock (locker) maxConcurrency = Math.Max(maxConcurrency, concurrency);
try
{
// Do work with the PDF page...
} finally { Interlocked.Decrement(ref concurrencyCounter); }
});
//...
await Task.WhenAll(tasks);
Debug.WriteLine($"Maximum concurrency: {maxConcurrency}");
Parallel
类或 AsParallel
PLINQ 运算符,也没有利用 Progress<T>
类,而且我怀疑使用未识别的 howManySearched
还存在竞争条件
和 pagesWithQuery
变量。