Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在一个线程中使用.net异步CTP_C#_Asynchronous_Tap_Ctp - Fatal编程技术网

C# 如何在一个线程中使用.net异步CTP

C# 如何在一个线程中使用.net异步CTP,c#,asynchronous,tap,ctp,C#,Asynchronous,Tap,Ctp,因此,我最近读了很多关于net Async CTP的书,其中有一句话不断出现:“异步不是关于启动新线程,而是关于多路复用工作”,“没有多线程的异步是同一个想法[作为协作多任务]。你做一个任务一段时间,当它产生控制时,你在该线程上做另一个任务一段时间” 我试图理解这样的评论是否纯粹(嗯,大部分是)深奥和学术性的,或者是否有一些我忽略的语言结构允许我通过“等待”启动的任务在UI线程上神奇地运行 Eric Lippert在他的博客中给出了这个示例,演示了如何在不使用多线程的情况下使用Asynchron

因此,我最近读了很多关于net Async CTP的书,其中有一句话不断出现:“异步不是关于启动新线程,而是关于多路复用工作”,“没有多线程的异步是同一个想法[作为协作多任务]。你做一个任务一段时间,当它产生控制时,你在该线程上做另一个任务一段时间”

我试图理解这样的评论是否纯粹(嗯,大部分是)深奥和学术性的,或者是否有一些我忽略的语言结构允许我通过“等待”启动的任务在UI线程上神奇地运行

Eric Lippert在他的博客中给出了这个示例,演示了如何在不使用多线程的情况下使用Asynchrony:

async void FrobAll()
{
    for(int i = 0; i < 100; ++i)
    {
        await FrobAsync(i); // somehow get a started task for doing a Frob(i) operation on this thread
    }
} 
async void FrobAll()
{
对于(int i=0;i<100;++i)
{
wait FrobAsync(i);//以某种方式启动任务,以便在此线程上执行Frob(i)操作
}
} 
现在,我在这里感兴趣的是一条评论:“…开始一项任务,在这个线程上执行Frob(i)操作”

这怎么可能呢?这主要是理论上的评论吗?到目前为止,我看到的唯一一个任务似乎不需要单独的线程的情况(好吧,除非检查代码,否则无法确定)是类似task.Delay()的东西,可以在不启动另一个线程的情况下等待它。但我认为这是一个特殊的情况,因为我没有编写代码。

对于那些希望从GUI线程中卸载自己的一些长时间运行的代码的普通用户,我们不是主要在讨论像Task.Run这样的操作来卸载我们的工作,而这不是在另一个线程中启动它吗?如果是这样的话,为什么要对不将Asynchrony与多线程混淆而袖手旁观呢?

请参阅我的

在CPU工作的情况下,您必须使用类似于
Task.Run
的方法在另一个线程中执行它。然而,还有很多工作不是CPU工作(网络请求、文件系统请求、计时器等等),并且每一项都可以封装在
任务中,而无需使用线程

请记住,在驱动程序级别,一切都是异步的。同步Win32 API只是方便的包装。

请参阅我的

在CPU工作的情况下,您必须使用类似于
Task.Run
的方法在另一个线程中执行它。然而,还有很多工作不是CPU工作(网络请求、文件系统请求、计时器等等),并且每一项都可以封装在
任务中,而无需使用线程


请记住,在驱动程序级别,一切都是异步的。同步Win32 API只是方便的包装。

不是100%确定,但从文章中可以看出,它允许windows消息(调整大小事件、鼠标单击等)在调用
FrobAsync
之间交错。大致类似于:

void FrobAll()
{
    for(int i = 0; i < 100; ++i)
    {
        FrobAsync(i); // somehow get a started task for doing a Frob(i) operation on this thread
        System.Windows.Forms.Application.DoEvents();
    }
}

没有每次迭代之间对
DoEvents
的讨厌调用。发生这种情况的原因是,调用wait会发送一条Windows消息,该消息将
FrobAsync
调用排队,允许在下一次蛙跳开始之前执行蛙跳之间发生的任何Windows消息。

不是100%确定,但从文章中可以看出,这似乎是在允许Windows消息(调整事件大小、鼠标单击等)在调用
FrobAsync
之间交错。大致类似于:

void FrobAll()
{
    for(int i = 0; i < 100; ++i)
    {
        FrobAsync(i); // somehow get a started task for doing a Frob(i) operation on this thread
        System.Windows.Forms.Application.DoEvents();
    }
}

在每次迭代之间,如果没有对
的恶意调用,则会发生事件。发生这种情况的原因是,对wait的调用会发送一条Windows消息,使
FrobAsync
调用排队,从而允许在下一次蛙跳开始之前执行蛙跳之间发生的任何Windows消息。

异步t
只是关于异步的。从调用方的角度来看,是否使用多个线程并不重要——只是它执行异步操作。例如,IO完成端口是异步的,但不执行任何多线程操作(操作的完成发生在后台线程上;但是“工作”没有在那个线程上完成)

wait
关键字来看,“多线程”毫无意义。异步操作所做的是一个实现细节

根据Eric的示例,该方法可以实现如下:

return Task.Factory.StartNew(SomeMethod, 
                             TaskScheduler.FromCurrentSynchronizationContext());
这实际上意味着在当前线程上对
SomeMethod
的调用完成所有当前排队的工作后进行排队。这与
FrobAsync
的调用方是异步的,因为
FrobAsync
很可能在执行
SomeMethod
之前返回

现在,
FrobAsync
可以实现为使用多线程,在这种情况下,它可以这样编写:

return Task.Factory.StartNew(SomeMethod);
如果默认的TaskScheduler没有更改,那么它将使用线程池。但是,从调用者的角度来看,没有任何变化——您仍然等待该方法


从多线程的角度来看,这是您应该看到的。使用
Task.Start
Task.Run
、或
Task.Factory.StartNew

/
wait
只是关于异步。从调用方来看,无论是否使用多个线程,都是简单的例如,IO完成端口是异步的,但不执行任何多线程(操作的完成发生在后台线程上;但“工作”没有在该线程上完成)

wait
关键字来看,“多线程”毫无意义。异步操作所做的是一个实现细节

根据Eric的示例,该方法可以实现如下:

return Task.Factory.StartNew(SomeMethod, 
                             TaskScheduler.FromCurrentSynchronizationContext());
这实际上意味着在当前线程上对
SomeMethod
的调用进行排队,当它完成所有任务时