Multithreading 第三方物流与;异步/等待(线程处理)
在创建线程时,尝试理解TPL和Multithreading 第三方物流与;异步/等待(线程处理),multithreading,task-parallel-library,async-await,c#-5.0,Multithreading,Task Parallel Library,Async Await,C# 5.0,在创建线程时,尝试理解TPL和异步/等待之间的差异 我相信TPL(TaskFactory.StartNew)的工作原理类似于ThreadPool.QueueUserWorkItem,它将线程池中某个线程上的工作排队。当然,除非您使用创建新线程的TaskCreationOptions.longlunning 我认为async/await在本质上也会起到类似的作用: 第三方物流: 异步/等待: await DoSomeAsyncWork(); DoSomeWorkAfter(); 都是一样的。
异步
/等待
之间的差异
我相信TPL(TaskFactory.StartNew
)的工作原理类似于ThreadPool.QueueUserWorkItem
,它将线程池中某个线程上的工作排队。当然,除非您使用创建新线程的TaskCreationOptions.longlunning
我认为async
/await
在本质上也会起到类似的作用:
第三方物流:
异步
/等待
:
await DoSomeAsyncWork();
DoSomeWorkAfter();
都是一样的。从我所读到的内容来看,似乎
async
/wait
只是“有时”创建一个新线程。那么它什么时候创建一个新线程,什么时候不创建一个新线程呢?如果你正在处理IO完成端口,我可以看到它不必创建一个新线程,否则我认为它必须创建一个新线程。我想我对CurrentSynchronizationContext的理解也总是有点模糊。我一直认为它本质上是UI线程。async/await基本上简化了ContinueWith的方法(Continuations in)
它不引入并发性——您仍然需要自己来实现(或者使用框架方法的异步版本)
因此,C#5版本将是:
await Task.Run( () => DoSomeAsyncWork() );
DoSomeWorkAfter();
我相信TPL(TaskFactory.Startnew)的工作原理与ThreadPool.QueueUserWorkItem类似,它将线程池中某个线程上的工作排队
从我所读到的内容来看,似乎async/Wait只是“有时”创建了一个新线程
事实上,从来没有。如果您想要多线程,您必须自己实现它。有一个新的Task.Run
方法,它只是Task.Factory.StartNew
的简写,可能是在线程池上启动任务的最常用方法
如果你正在处理IO完成端口,我可以看到它不必创建一个新线程,否则我认为它必须创建一个新线程
宾果。因此像Stream.ReadAsync
这样的方法实际上会在IOCP周围创建一个任务
包装器(如果流
有一个IOCP)
您还可以创建一些非I/O、非CPU的“任务”。一个简单的例子是Task.Delay
,它返回一个在一段时间后完成的任务
async
/wait
最酷的一点是,您可以将一些工作排队到线程池(例如,Task.Run
),执行一些I/O绑定操作(例如,Stream.ReadAsync
),以及执行一些其他操作(例如,Task.Delay
)。。。它们都是任务!它们可以等待或组合使用,如Task.whalll
任何返回Task
的方法都可以是wait
ed-它不必是async
方法。因此,Task.Delay
和I/O绑定操作只需使用TaskCompletionSource
创建和完成任务-线程池上唯一要做的事情就是事件发生时的实际任务完成(超时、I/O完成等)
我想我对FromCurrentSynchronizationContext的理解也总是有点模糊。我一直认为它本质上是UI线程
我写了SynchronizationContext
。大多数情况下,SynchronizationContext.Current
:
- 如果当前线程是UI线程,则为UI上下文
- 如果当前线程正在为ASP.NET请求提供服务,则为ASP.NET请求上下文
- 否则是线程池上下文
任何线程都可以设置自己的SynchronizationContext
,因此上述规则也有例外
请注意,默认的任务
等待程序将在当前同步上下文
上安排异步
方法的其余部分(如果该方法不为空);否则它将在当前的任务调度器上运行。这在今天并不重要,但在不久的将来,这将是一个重要的区别
我在我的博客上写了我自己的,斯蒂芬·图布最近发表了一篇精彩的文章
关于“并发”与“多线程”,请参阅。我想说,async
支持并发,这可能是多线程的,也可能不是。使用等待任务很容易。当所有或等待任务。当任何执行并发处理时,除非您明确使用线程池(例如任务。运行或配置等待(false)
),否则您可以同时执行多个并发操作(例如,多个I/O或其他类型,如Delay
)-它们不需要线程。对于这种情况,我使用术语“单线程并发”,尽管在ASP.NET主机中,您实际上可以得到“零线程并发”。这很好。那么它在哪里运行DoSomeAsyncWork(异步/等待版本)在我上面的示例中?如果它在UI线程上运行,它如何不阻塞?如果DoSomeWorkAsync(),等待示例将不会编译
返回void或不可等待的内容。从您的第一个示例中,我假设它是一个顺序方法,您希望在不同的线程上运行。如果您将它更改为返回一个任务,而不引入并发性,则它将阻塞。从某种意义上说,它将按顺序执行,与普通代码一样在UI线程上。await
仅当该方法返回尚未完成的等待时才会产生。好吧,我不会说它在它选择运行的任何地方运行。您已经使用Task.run在DoSomeAsyncWork中执行代码,因此在这种情况下,您的工作将在线程池线程上完成。我喜欢您的简洁回答。实际上,TaskCreationOptions.LongRunning不保证“新线程”。根据MSDN,“LongRunning”选项仅向调度程序提供提示;它提供提示
await Task.Run( () => DoSomeAsyncWork() );
DoSomeWorkAfter();