我怎么在ConfiguredTaskAwaitable上".Wait()"?

Wil*_*ill 7 c# asynchronous async-await

给出以下扩展以防止Tasks阻塞UI线程(可能不是完全正确的术语,但无论如何):

    public static ConfiguredTaskAwaitable DontBlock( this Task T ) {
        return T.ConfigureAwait( false );
    }

    public static ConfiguredTaskAwaitable<T> DontBlock<T>( this Task<T> T2 ) {
        return T2.ConfigureAwait( false );
    }
Run Code Online (Sandbox Code Playgroud)

在某些情况下(例如,如果我需要在对象构造函数中调用awaitable,或者如果我需要.Wait( )从WinForms Program.Main( )方法调用),我需要执行以下操作:

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( );
    }
}
Run Code Online (Sandbox Code Playgroud)

async如果我不能打电话.Wait( ),如何在函数/方法之外"等待" 它?我看到它有一个.GetAwaiter( )方法可以返回一个ConfiguredTaskAwaiter对象,但是我不知道该怎么做,谷歌再次让我失望了...我应该立即调用GetResult( )返回的对象吗?这样做会等待一切都完成,或者只是跳过它,或者爆炸?

usr*_*usr 10

也许,你不应该ConfiguredTaskAwaitable从任何东西返回.这是一种只在await t.ConfigureAwait( false)模式中需要的辅助类型.await t.DontBlock()也很好,但不要通过这种类型.我认为这样做没有任何意义.

您似乎相信ConfigureAwait(false)取消阻止UI线程.不是这样.等待总是阻塞一个线程.阻止意味着此线程无法继续执行.Wait如果基础任务未完成,则会导致该情况.

所以可能,你想要完成的事情还没有完成.使用awaitUI线程.Wait()如果要阻止,请在非UI线程上使用.

AwaitableBar.DontBlock( ).Wait()告诉我你有一些错误的信念.在这里,DontBlock不会解锁任何东西.即使这段代码有效,它也什么都不做.

如果解锁线程很容易,为什么我们需要呢await?!


Chi*_*ael 7

我同意@usr回归a ConfiguredTaskAwaitable并不理想.通常,您的异步方法应该返回任务.这是一个关注点分离的问题.

ConfiguredTaskAwaitable但是,只要你有一个电话awaitableObj.GetAwaiter().GetResult()(或适当的替代).GetResult()会阻止.

  • 不管我的问题多么愚蠢和愚蠢,这就是我正在寻找的答案;谢谢。 (2认同)