我怎么在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 ?!