C# 有没有一种巧妙的方法可以强制一堆“async”C代码以单线程方式运行,就好像它不是&x27;实际上是异步的`

C# 有没有一种巧妙的方法可以强制一堆“async”C代码以单线程方式运行,就好像它不是&x27;实际上是异步的`,c#,multithreading,asynchronous,task-parallel-library,C#,Multithreading,Asynchronous,Task Parallel Library,假设(完全假设)我有一大堆async代码 10秒级;100个异步方法,其中10个实际执行异步工作(例如,当我们WriteToDbAsync(数据)或我们ReadFileFromInternetAsync(uri),或当所有(并行任务)时) 我想对它进行一系列的诊断调试,我想对它进行性能分析,然后手动进行一系列的测试,看看是什么 我所有的工具都是围绕同步C#code设计的。它们在某种程度上可以与异步配合使用,但效率肯定要低得多,调试也要困难得多,即使我尝试直接管理线程一点 如果我只对代码的一小部分

假设(完全假设)我有一大堆
async
代码

10秒级;100个异步方法,其中10个实际执行异步工作(例如,当我们
WriteToDbAsync(数据)
或我们
ReadFileFromInternetAsync(uri)
,或当
所有(并行任务)
时)

我想对它进行一系列的诊断调试,我想对它进行性能分析,然后手动进行一系列的测试,看看是什么

我所有的工具都是围绕同步C#code设计的。它们在某种程度上可以与
异步
配合使用,但效率肯定要低得多,调试也要困难得多,即使我尝试直接管理线程一点

如果我只对代码的一小部分感兴趣,那么暂时取消对该部分代码的异步读写肯定会容易得多。同步读写,在我的每一个“并行”上都执行Task.Wait()
Task
s按顺序进行。但如果我想在大量代码中浏览,这是不可行的

是否有必要要求C#为我运行一些类似的“
async
”代码?

i、 e.某种类型的
(()=>MyAsyncMethod())。运行AsyncDidnExist()
,它知道任何时候它与外部世界进行真正的异步通信时,它应该只是旋转(在同一线程内)在得到答案之前。任何时候当它被要求并行运行代码时……不要这样做;只需在它的单个线程上串行运行它们。等等

我不是说等待任务完成,或者调用
Task.Wait()
。这些都不会改变任务本身执行的方式


我强烈地认为这类东西不存在,我只能忍受我的工具没有针对
async
代码进行良好的架构

但如果有人在这方面有一些专业知识,能够证实这一点,那就太好了


编辑:(因为苏告诉我为什么这个建议不是答案)。。。
西纳特建议:但是(据我所知)这将确保每次有
await
命令时,
await
之后的代码继续在同一线程上运行。但是我希望
await
的实际内容在同一线程上。

请记住异步!=并行

  • 并行意味着同时运行两段或多段代码,这只能通过多线程来完成。它是关于代码如何运行的
  • 异步代码使当前线程在等待其他操作时可以自由地执行其他操作。它是关于代码如何等待的
具有同步上下文的异步代码可以在单个线程上运行。它开始在一个线程上运行,然后在等待时发出I/O请求(如HTTP请求)。然后继续(因为存在同步上下文)可能发生在同一线程上,具体取决于同步上下文的要求,例如在UI应用程序中,延续发生在UI线程上

如果没有同步上下文,则可以在任何线程池线程上运行延续(但仍可能发生在同一线程上)

因此,如果您的目标是让它最初运行,然后在同一个线程上恢复,那么这确实是最好的方法,因为同步上下文决定了如何执行延续

但是,如果有任何对
Task.Run
的调用,这对您没有帮助,因为该方法的全部目的是启动一个新线程(并为您提供一种异步方式来等待该线程完成)

如果代码在任何
await
调用中使用
.ConfigureAwait(false)
,也可能没有帮助,因为这明确表示“我不需要在同步上下文上恢复”,因此它可能仍然在线程池线程上运行。我不知道Stephen的解决方案是否为此做了什么

但是,如果您确实希望它“runashoughtasyncdindentexist”并在等待时锁定当前线程,那么这是不可能的。以下面的代码为例:

var myTask = DoSomethingAsync();
DoSomethingElse();
var results = await myTask;

此代码启动I/O请求,然后在等待该请求完成时执行其他操作,然后完成等待并在之后处理结果。使其同步运行的唯一方法是重构它,因为同步代码在等待时无法执行其他工作。必须决定是否执行I/O请求/O在
DoSomethingElse()之前或之后请求

希望Stephen Cleary出现:d这听起来与
任务的用例非常相似。Wait
。你能解释一下为什么
任务。Wait
对你不起作用吗?你所说的“它不会改变任务本身执行的方式”是什么意思?这回答了你的问题吗?@Sinatr我不认为这完全是它-它决定了任务运行后如何继续,但我不认为它决定了任务本身运行的位置?我不确定:(它肯定需要成为整个事情的一部分?@Brondahl“希望Stephen Cleary出现”-他不仅仅是“出现”。他必须被传唤。:d谢谢你。这或多或少是我所期望听到的-没有什么事情可以做,因为这与编写异步和并行代码的概念是不相容的。FWIW,关于你的最后一点,我的意思是“代码转换器/替代编译器”删除异步和并行化。例如,当它看到
Task.Run()
时,它不会在一个新的
任务上启动它
——它只是“打开”任务
,并直接在同一个线程上执行操作。因此在您的代码示例中,它将完全执行
DoSomethingAsync()
在进入下一行之前(…而不是因为它
.Wa