Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
Multithreading 第三方物流与;异步/等待(线程处理)_Multithreading_Task Parallel Library_Async Await_C# 5.0 - Fatal编程技术网

Multithreading 第三方物流与;异步/等待(线程处理)

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和
异步
/
等待
之间的差异

我相信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();