Task-Like和ConfigureAwait(false),有可能吗?

Task-Like and ConfigureAwait(false), is it possible?

我一直在阅读类似任务和可等待的类型。我想我已经很好地掌握了它的基本机制(等待者、asyncmethodbuilder ...),但是当我试图理解 ConfigureAwait(false) 在这种情况下的用法时(如果可能的话),有些不对劲。

我的问题是:

ConfigureAwait 是否为“真实”任务保留,意味着是否使用 SynchronizationContext?

如果是这样,假设您正在编写一个公开其自己的类任务类型实现的通用库,您是否应该在代码遇到任务时只使用 ConfigureAwait(false)?

谢谢。

如果您的图书馆的类任务类型在等待时没有捕获上下文,那么您图书馆的用户将无法执行此操作:

private async void Button_Click(object sender, EventArgs e)
{
    string input = Textbox1.Text;
    TaskLike<string> taskLike = YourLibrary.ProcessAsync(input);
    string result = await taskLike;
    Label1.Text = result // InvalidOperationException: Cross-thread operation not valid
}

另一方面,如果您的库的类任务类型总是在等待时捕获同步上下文,那么您的库作为其他库的构建块将效率低下,并且需要其他库作者 以便以同步上下文无关的方式调用您的库。因此,使您的类似任务的类型在捕获同步上下文方面可配置应该是一个可取的功能。

关于当您的库的内部代码遇到标准 Task 时是否应该使用 ConfigureAwait(false),这取决于您的库是否接受调用者提供的 lambda。例如,如果您的库包含这样的方法:

public TaskLike<string> ProcessAsync(Action action);

...然后在内部等待 ConfigureAwait(false) 之后调用 action 可能会导致跨线程违规异常,如果调用者的 lambda 包含线程仿射代码,例如读取 [= 的属性27=] 控件。要解决此问题,可能需要在方法的签名中引入配置参数 continueOnCapturedContext。至少这是 Polly library.

选择的解决方案