异步 - 停留在当前线程上? [英] async - stay on the current thread?

查看:116
本文介绍了异步 - 停留在当前线程上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过埃里克利珀<一个href=\"http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx\"相对=nofollow> 文章异步,以及有关的人混淆曾与异步关键字。他说:

I've read Eric lippert article about async , and about confusions people had with async keyword. he said :

它(异步)的意思是这个方法中包含涉及等待控制流
  异步操作,因此将被改写
  编译器为延续传递风格,以确保
  异步操作可以继续在正确的位置这种方法。整点的异步方法它,你留在当前线程尽可能在

it (async) means "this method contains control flow that involves awaiting asynchronous operations and will therefore be rewritten by the compiler into continuation passing style to ensure that the asynchronous operations can resume this method at the right spot." The whole point of async methods it that you stay on the current thread as much as possible

我不明白这一点。如果我执行异步方法(工作),它运行时,它的肯定的运行在另一个线程。

I don't understand this. If I execute an asynchronous method (Task) and it runs , it surely runs on another thread.

此外,如果我写的方法使用等待,(恕我直言)它会释放正常的控制流和code是的重构的一点通 ContinueWith 后,在其他主题。

Moreover , If I write a method uses await , (imho) it releases the normal control flow , and code is refactored alike "ContinueWith" later , on 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

那么,什么也埃里克说留在当前线程上呢?

So what did Eric mean by saying "stay on the current thread"?

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

in asp.net it also return differnt thread 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

修改2

(得到答案之后)

似乎线程只能在GUI应用服务。我运行这个code。在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;
        }

推荐答案

中添加了异步/的await支持,以帮助程序员编写不冻结的GUI。尤其适用于存储应用,它被添加到C#V5的核心原因,WinRT的是pretty不友好的API,它具有的许多的异步方法。

The async/await support was added to help programmers write GUIs that don't freeze. Particularly useful in Store apps, and the core reason it was added to C# v5, WinRT is a pretty unfriendly api that has many asynchronous methods.

在停留在同一线程上的情景是的非常的一个GUI应用程序重要的,必需的,因为GUI不是线程安全的。然而,这确实需要一个消息循环,让异步code,继续在同一线程上的唯一途径。消息循环的核心是解决生产者消费者问题。显然,你的程序不有一个,看起来很像一个控制台模式的应用程序。因此,你没有得到这样的行为,继续在工作线程。

The "stay on the same thread" scenario is very important in a GUI app, required because a GUI isn't thread-safe. It does however require a message loop, the only way to get asynchronous code to resume on the same thread. The message loop is the core solution to the producer-consumer problem. Clearly your program doesn't have one, looks a lot like a console mode app. You therefore don't get this behavior, it resumes on a worker thread.

不是太大的问题,你不实际的需求的它可以继续在同一线程上,因为一个控制台是线程安全的反正。好了,主要是,这还不包括当你要求输入被添加在.NET 4.5的锁。当然,这也意味着,你不必使用了异步的heckofalot /等待,那么一个任务正常工作为好。

Not much of a problem, you don't actually need it to resume on the same thread since a console is thread-safe anyway. Well, mostly, not counting the lock that was added in .NET 4.5 when you ask for input. Which of course also means that you don't have a heckofalot of use for async/await either, a Task works fine as well.

这篇关于异步 - 停留在当前线程上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆