我怎么在ConfiguredTaskAwaitable上“.Wait()”?
给出以下扩展以防止Tasks
阻止UI线程(可能不是完全正确的术语,但无论如何):
public static ConfiguredTaskAwaitable DontBlock( this Task T ) { return T.ConfigureAwait( false ); } public static ConfiguredTaskAwaitable DontBlock( this Task T2 ) { return T2.ConfigureAwait( false ); }
在某些情况下(例如,如果我需要在对象构造函数中调用awaitable,或者如果我需要从WinForms Program.Main( )
方法调用.Wait( )
),我需要执行以下操作:
public class Foo{ public Foo( ){ //I know full well that the result from DontBlock does not have a 'wait' method, so of course this will fail miserably. AwaitableBar.DontBlock( ).Wait( ); } }
如果我不能在它上面调用.Wait( )
,我如何在async
函数/方法之外’等待’它? 我看到它有一个.GetAwaiter( )
方法,它返回一个ConfiguredTaskAwaiter
对象,但我不知道该怎么办,谷歌再次让我失望……我应该在返回的对象上调用GetResult( )
远? 这样做会等待一切都完成,或者只是跳过它,或者爆炸?
我同意@usr,返回一个ConfiguredTaskAwaitable
并不理想。 通常,您的异步方法应该返回任务。 这是一个关注点分离的问题。
但是,一旦你有了ConfiguredTaskAwaitable
,只需调用awaitableObj.GetAwaiter().GetResult()
(或相应的替换)。 GetResult()
将阻止。
可能你不应该从任何东西返回一个ConfiguredTaskAwaitable
。 这是一个辅助类型,仅在await t.ConfigureAwait( false)
模式时需要。 await t.DontBlock()
也没问题,但不要传递这种类型。 我认为这样做没有任何意义。
您似乎相信ConfigureAwait(false)
取消阻止UI线程。 不是这样。 等待总是阻塞一个线程。 阻止意味着此线程无法继续执行。 如果基础任务未完成,则Wait
导致该条件。
所以可能,你想要完成的事情还没有完成。 在UI线程上使用await
。 如果要阻止,请在非UI线程上使用Wait()
。
AwaitableBar.DontBlock( ).Wait()
告诉我你有一些错误的信念。 在这里, DontBlock
不会解锁任何东西。 即使这段代码有效,它也什么都不做。
如果解锁一个线程很容易,为什么我们需要await
?!