异步 - 留在当前线程上?

2024-01-08

我读过埃里克·利珀特的article http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx about async,以及人们的困惑async关键词。他说 :

it (async) 表示“该方法包含涉及等待的控制流 异步操作,因此将被重写 编译器进入连续传递风格以确保 异步操作可以在正确的位置恢复此方法。”异步方法的重点是尽可能留在当前线程上

我不明白这一点。如果我执行一个异步方法(Task)并且它运行,它surely在另一个线程上运行。

而且,如果我写一个方法使用await,(恕我直言)它释放了正常的控制流,代码是重构的一样 ”ContinueWith“ 稍后的another thread.

我用(控制台)测试了它:

/*1*/   public void StartChain()
/*2*/   {
/*3*/           var a = FuncA();
/*4*/           Console.WriteLine(a.Result);
/*5*/   }
/*6*/   
/*7*/   public async Task < int > FuncA()
/*8*/   {
/*9*/           Console.WriteLine("A--" + Thread.CurrentThread.ManagedThreadId);
/*10*/           var t = await FuncB();
/*11*/           Console.WriteLine("B--" + Thread.CurrentThread.ManagedThreadId);
/*12*/           return t;
/*13*/   }
/*14*/   
/*15*/   public async Task < int > FuncB()
/*16*/   {
/*17*/           Console.WriteLine("C--" + Thread.CurrentThread.ManagedThreadId);
/*18*/           await Task.Delay(2000);
/*19*/           Console.WriteLine("D--" + Thread.CurrentThread.ManagedThreadId);
/*20*/           return 999;
/*21*/   }
/*22*/   
/*23*/   void Main()
/*24*/   {
/*25*/           StartChain();
/*26*/   }
/*27*/   

结果是:

A--7
C--7
D--17         <-----D  and B are on different thread
B--17
999

那么埃里克所说的“留在当前线程”是什么意思呢?

edit 1:

in asp.net它还返回不同的线程ID。

public async Task<int> FuncA()
{
    Response.Write("<br/>C----" + Thread.CurrentThread.ManagedThreadId);
    var t = await FuncB();
    Response.Write("<br/>D----" + Thread.CurrentThread.ManagedThreadId);
    return t;
}

public async Task<int> FuncB()
{
    Response.Write("<br/>E----" + Thread.CurrentThread.ManagedThreadId);
    await Task.Delay(2000);
    Response.Write("<br/>F----" + Thread.CurrentThread.ManagedThreadId);
    return 999;
}



protected async void Page_Load(object sender, EventArgs e)
{
    Response.Write("<br/>A----" + Thread.CurrentThread.ManagedThreadId);
    var a=await FuncA();
    Response.Write("<br/>B----" + Thread.CurrentThread.ManagedThreadId);

}

A----8
C----8
E----8
F----9
D----9
B----9

edit 2

(得到答复后)

看来线程只在 GUI 应用程序中提供服务:.我在 winform 中运行这段代码

  public async Task<int> FuncA()
        {
            textBox1.Text +=Environment.NewLine+ "\nC----" + Thread.CurrentThread.ManagedThreadId;
            var t = await FuncB();
            textBox1.Text += Environment.NewLine + "\nD----" + Thread.CurrentThread.ManagedThreadId;
            return t;
        }

        public async Task<int> FuncB()
        {
            textBox1.Text += Environment.NewLine + "\nE----" + Thread.CurrentThread.ManagedThreadId;
            await Task.Delay(2000);
            textBox1.Text += Environment.NewLine + "\nF----" + Thread.CurrentThread.ManagedThreadId;
            return 999;
        }




        private async void Form1_Load(object sender, EventArgs e)
        {
            textBox1.Text += Environment.NewLine + "\nA----" + Thread.CurrentThread.ManagedThreadId;
            var a = await FuncA();
            textBox1.Text += Environment.NewLine + "\nB----" + Thread.CurrentThread.ManagedThreadId;
        }

如果我执行一个异步方法并且它运行,它肯定在另一个线程上运行。

No, it 通常在另一个线程上运行。它不是surely在另一个线程上运行。

暂时停止考虑线程,考虑一下异步的本质。异步的本质是:

  • 我当前正在执行一些工作流程。
  • 在获得信息 X 之前,我无法继续此工作流程。
  • 在获得 X 信息之前我会做其他事情。
  • 在未来的某个时刻,一旦我有了 X,我就会回到工作流程中中断的地方并继续。

假设您正在办理报税,并且在这个复杂的工作流程中您需要执行大量附加操作。然后就可以进行一些操作了记住你在哪里,然后去吃午饭。然后回来再执行几个操作,然后记住你在哪里,然后喂猫。然后回来再执行几个操作,然后记住你在哪里,然后洗碗。然后完成计算,并从工作流程中断处继续。

这是一个异步计算,但只需要一个工作人员来完成。拥有多个工作人员只是一种特别方便的异步方式,而不是必需的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

异步 - 留在当前线程上? 的相关文章

  • 使用 PushStreamContent 从 HTTPClient 上传

    我想将大量数据上传到网络服务器from客户端机器 我直接跳到 PushStreamContent 这样我就可以直接写入流 因为结果的大小各不相同 并且可能相当大 流程如下 User runs query gt Reader Ready Ev
  • 如何正确阻止异步代码?

    我有大量以以下方式编写的代码 public string SomeSyncOperation int someArg sync code SomeAsyncOperation someArg someOtherArg ConfigureAw
  • 您应该在 Windows 8 应用程序的哪个位置编写“隐私策略”代码?

    我的应用程序未通过认证 原因是 4 1 1 如果您的应用程序具有网络功能 则必须有隐私声明 您必须在应用程序的说明页面以及 Windows 设置超级按钮中显示的应用程序设置中提供对隐私政策的访问权限 他们在说什么 什么描述 如何设置 Win
  • ServiceStack:异步/等待服务处理程序

    我读过一些涉及这个问题的问题 尽管其中许多已经有好几年了 如何在 ServiceStack API 中编写 Service 处理程序 使其成为 async await docs servicestack net 上没有任何文档提到 asyn
  • WPF应用程序,在打开窗口之前运行异步任务

    我遇到了一个问题 我需要在主窗口打开并显示之前运行异步任务 IE STAThread static void Main string args MainWindow window new MainWindow SplashScreen Sh
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • Cypress.io 如何处理异步代码

    我正在将旧的水豚测试转移到 cypress io 因为我们的应用程序正在采用 SPA 方式 在我们的案例中 我们有超过 2000 个测试 涵盖了很多功能 因此 测试功能的常见模式是让用户创建并发布报价 一开始我写了 cypress 浏览页面
  • 如果finally 块包含await,为什么*有时*不会在ThreadAbortException 上执行?

    UPDATE 我不认为这个问题是重复的ThreadAbortException最后可以跳过吗 https stackoverflow com questions 18002668 can threadabortexception skip
  • 如何在 RxJS 订阅方法中等待

    在 RxJS 主题的订阅回调内部 我想要await on an async功能 下面是打字稿转译器抱怨的代码示例 错误 131 21 TS2304 找不到名称 await async ngOnInit this subscriber dat
  • 从 Firestore 获取值并使用异步将输出存储为全局

    我正在尝试获取 firestore 数据 然后将其存储在变量中 async function getchildContent Parent Message let count 0 var db firebase firestore var
  • 为什么等待冷任务不会抛出

    我只是在尝试看看当一个冷任务 即一个任务 时会发生什么Task尚未开始 正在等待 令我惊讶的是 代码永远挂起并且 完成的 永远不会被打印 我希望抛出异常 public async Task Test1 var task new Task g
  • Typescript,装饰异步函数

    我正在尝试用一些异步函数 2 来装饰异步函数 1 E g function func2 param return target any propertyKey string descriptor PropertyDescriptor gt
  • 异步尝试(blah)模式[重复]

    这个问题在这里已经有答案了 我正在寻找有关如何处理以下情况的建议 我正在创建尝试获取某些数据的方法 遵循以下模式 Typical pattern public bool TryBlah string key out object value
  • Api 控制器中长时间运行的任务(使用 Web API,自托管 OWIN)

    我想在自托管 OWIN 环境中的 ApiController 中运行长时间运行的任务 例如 4 5 分钟 但是 我想在开始该任务后 一旦开始长时间运行的任务 就发回响应 而不等待它完成 这个长时间运行的任务与 HTTP 无关 并且顺序运行一
  • VB.NET vNext 中的迭代器以及 C# 中迭代​​器的限制

    我刚刚在上看到异步CTP网站 http msdn microsoft com en us vstudio async aspxVB NET 的下一个版本将有迭代器 我猜它们包含了迭代器 因为重写过程与新的迭代器所使用的过程类似 async
  • 调用异步方法在视图模型的构造函数中加载数据有警告

    我的视图包含一个 ListView 它显示来自互联网的一些数据 我创建一个异步方法来加载数据并在我的视图模型的构造函数中调用该方法 它有一个警告提示我现在使用await关键字 还有其他解决方案可以在构造函数中异步加载数据吗 有几种可以应用的
  • 使用 System.Json 迭代 JSON

    我正在探索 NET 4 5 的功能System Json库 但没有太多文档 而且由于流行的 JSON NET 库 搜索起来相当棘手 我基本上想知道 我如何循环一些 JSON 例如 People Simon Age 25 Steve Age
  • 如何调用进行 API 调用的类的实例以及该类中发出请求的函数,并将其分配给变量?迅速

    这是以下问题的后续 为什么代码不在第二个 URLSession shared dataTask 之后 之内执行 即在初始 URLSession shared dataTask 的 do 块内 迅速 https stackoverflow c
  • Task.Run 作为反模式?

    我正在将 SQLite NET PCL 库用于我的 WinRT 项目SQliteAsyncConnection类 它提供经典的异步版本SQLiteConnection方法 然而 就该项目而言Github页面 https github com
  • 如何在 C# 中创建异步方法?

    我读过的每一篇博客文章都会告诉您如何在 C 中使用异步方法 但由于某些奇怪的原因 从未解释如何构建您自己的异步方法来使用 所以我现在有这段代码使用我的方法 private async void button1 Click object se

随机推荐