异步等待新线程的行为
Behavior of async await with new threads
我正在尝试了解 async/await 的确切行为,但在思考它时遇到了一些麻烦。
考虑这个例子:
public async void StartThread()
{
while(true){
SomeOtherClass.SomeSynchronousStuff();
var something = await SomeOtherClass.SomeOtherAsyncMethod();
}
}
public void ConstructorForThisClass()
{
Thread thread = new Thread(StartThread);
thread.Start();
}
我对 async/await 的理解是,在幕后发生的事情是编译器实质上将您的代码转换为一堆回调并为每个回调存储状态对象。
所以根据这个,我的问题是:
- 新建线程会不会运行异步?意思是,当线程正在等待
SomeOtherAsyncMethod
时,它会被释放出来处理其他工作吗?
- 如果上述情况成立,当
SomeOtherAsyncMethod
returns 时,线程是否会简单地结束并由一个线程池线程取而代之?
- 如何在线程池线程而不是托管线程上发出
StartThread
函数?
- 当一个可等待的方法 returns 到它的调用者时,它是强制在调用它的线程上恢复还是可以有任何空闲线程代替它?
Will the newly created thread be running asynchronously?
你的措辞有点问题。线程的创建是完全同步的。
Meaning, while the thread is awaiting the SomeOtherAsyncMethod, will it be
freed up to work on other work?
您正在使用 Thread
class 手动创建线程,而不是线程池线程。它不在 AppDomain 内共享。一旦遇到第一个 await
关键字,它 将 被释放,但是由于你在无休止的 while
循环中使用它,它不会被用于任何除此之外的其他工作。
If the preceding is true, will the thread simply end and a thread pool
thread take its place when the SomeOtherAsyncMethod returns?
忽略前者,因为您不使用 ConfigureAwait(false)
,那么延续将在任意 ThreadPool 线程上 运行。但这真的取决于上下文。由于您在新线程上 运行ning 这个委托,所以会发生这种情况。但是,如果您是 运行 来自 UI 线程的,那么继续将尝试通过相关的 TaskScheduler
和对应SynchronizationContext
.
How would I go about issuing the StartThread function on a thread pool
thread rather than a managed thread?
由 Thread
class 和 ThreadPool
class 启动的所有线程都是 管理的 线程。如果您的意思是 "How do i run this delegate on the threadpool",那么答案是通过 Task.Run
或通过 ThreadPool
静态 class.
When an awaitable method returns to its caller, is it forced to resume
on the thread that calls it or can any free thread take its place?
如果 运行 没有 ConfigureAwait(false)
,它会被强制到当前 TaskScheduler
及其底层 SynchronizationContext
。这意味着如果你在 UI 消息循环中 运行,并在那里调用 await
,它将尝试 post 继续它。如果没有自定义 TaskScheduler
可用,它将使用默认的,即线程池调度程序。
裸线程不适用于 async
/await
。
Will the newly created thread be running asynchronously? Meaning, while the thread is awaiting the SomeOtherAsyncMethod, will it be freed up to work on other work?
实际上,线程将退出。当 StartThread
在 await
之后恢复时,它将在线程池线程上执行。
How would I go about issuing the StartThread function on a thread pool thread rather than a managed thread?
首先,您需要将 StartThread
的 return 类型从 void
更改为 Task
。 async void
方法用于事件处理程序;在其他地方使用它们会导致各种问题。
然后你可以通过Task.Run
调用它:
var backgroundTask = Task.Run(() => StartThread());
When an awaitable method returns to its caller, is it forced to resume on the thread that calls it or can any free thread take its place?
默认情况下,await
运算符将捕获 "current context" 并在该上下文 上恢复 。这个 "current context" 是 SynchronizationContext.Current
,除非它是 null
,在这种情况下它是 TaskScheduler.Current
。通常,这要么是 UI/ASP.NET SynchronizationContext
,要么是线程池上下文 (TaskScheduler.Default
).
您可能会发现我的 async
intro 很有帮助。
我正在尝试了解 async/await 的确切行为,但在思考它时遇到了一些麻烦。
考虑这个例子:
public async void StartThread()
{
while(true){
SomeOtherClass.SomeSynchronousStuff();
var something = await SomeOtherClass.SomeOtherAsyncMethod();
}
}
public void ConstructorForThisClass()
{
Thread thread = new Thread(StartThread);
thread.Start();
}
我对 async/await 的理解是,在幕后发生的事情是编译器实质上将您的代码转换为一堆回调并为每个回调存储状态对象。
所以根据这个,我的问题是:
- 新建线程会不会运行异步?意思是,当线程正在等待
SomeOtherAsyncMethod
时,它会被释放出来处理其他工作吗? - 如果上述情况成立,当
SomeOtherAsyncMethod
returns 时,线程是否会简单地结束并由一个线程池线程取而代之? - 如何在线程池线程而不是托管线程上发出
StartThread
函数? - 当一个可等待的方法 returns 到它的调用者时,它是强制在调用它的线程上恢复还是可以有任何空闲线程代替它?
Will the newly created thread be running asynchronously?
你的措辞有点问题。线程的创建是完全同步的。
Meaning, while the thread is awaiting the SomeOtherAsyncMethod, will it be freed up to work on other work?
您正在使用 Thread
class 手动创建线程,而不是线程池线程。它不在 AppDomain 内共享。一旦遇到第一个 await
关键字,它 将 被释放,但是由于你在无休止的 while
循环中使用它,它不会被用于任何除此之外的其他工作。
If the preceding is true, will the thread simply end and a thread pool thread take its place when the SomeOtherAsyncMethod returns?
忽略前者,因为您不使用 ConfigureAwait(false)
,那么延续将在任意 ThreadPool 线程上 运行。但这真的取决于上下文。由于您在新线程上 运行ning 这个委托,所以会发生这种情况。但是,如果您是 运行 来自 UI 线程的,那么继续将尝试通过相关的 TaskScheduler
和对应SynchronizationContext
.
How would I go about issuing the StartThread function on a thread pool thread rather than a managed thread?
由 Thread
class 和 ThreadPool
class 启动的所有线程都是 管理的 线程。如果您的意思是 "How do i run this delegate on the threadpool",那么答案是通过 Task.Run
或通过 ThreadPool
静态 class.
When an awaitable method returns to its caller, is it forced to resume on the thread that calls it or can any free thread take its place?
如果 运行 没有 ConfigureAwait(false)
,它会被强制到当前 TaskScheduler
及其底层 SynchronizationContext
。这意味着如果你在 UI 消息循环中 运行,并在那里调用 await
,它将尝试 post 继续它。如果没有自定义 TaskScheduler
可用,它将使用默认的,即线程池调度程序。
裸线程不适用于 async
/await
。
Will the newly created thread be running asynchronously? Meaning, while the thread is awaiting the SomeOtherAsyncMethod, will it be freed up to work on other work?
实际上,线程将退出。当 StartThread
在 await
之后恢复时,它将在线程池线程上执行。
How would I go about issuing the StartThread function on a thread pool thread rather than a managed thread?
首先,您需要将 StartThread
的 return 类型从 void
更改为 Task
。 async void
方法用于事件处理程序;在其他地方使用它们会导致各种问题。
然后你可以通过Task.Run
调用它:
var backgroundTask = Task.Run(() => StartThread());
When an awaitable method returns to its caller, is it forced to resume on the thread that calls it or can any free thread take its place?
默认情况下,await
运算符将捕获 "current context" 并在该上下文 上恢复 。这个 "current context" 是 SynchronizationContext.Current
,除非它是 null
,在这种情况下它是 TaskScheduler.Current
。通常,这要么是 UI/ASP.NET SynchronizationContext
,要么是线程池上下文 (TaskScheduler.Default
).
您可能会发现我的 async
intro 很有帮助。