非通用TaskCompletionSource或替代

Kev*_*ski 62 .net c# async-await

我正在使用通常以异步方式显示的警报窗口(Telerik WPF)(代码在打开时继续运行),我想通过使用async/await使其同步.

我有这个工作,TaskCompletionSource但该类是通用的,并返回一个对象,就像Task<bool>我想要的只是一个Task没有返回值的普通.

public Task<bool> ShowAlert(object message, string windowTitle)
{
    var dialogParameters = new DialogParameters { Content = message };

    var tcs = new TaskCompletionSource<bool>();
    dialogParameters.Closed += (s, e) => tcs.TrySetResult(true);

    RadWindow.Alert(dialogParameters);

    return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)

调用该方法的代码是

await MessageBoxService.ShowAlert("The alert text.")
Run Code Online (Sandbox Code Playgroud)

如何返回一个非常规的Task,其功能类似于我可以等到dialogParameters.Closed事件触发之前?我知道我可以忽略bool在此代码中返回的内容.我正在寻找一种不同的解决方案.

Kev*_*ski 87

该方法可以更改为:

public Task ShowAlert(object message, string windowTitle)
Run Code Online (Sandbox Code Playgroud)

Task<bool>Task从而继承,Task<bool>只有暴露Task给调用者才能返回

编辑:

我在Stephen Toub 发现了一个名为"基于任务的异步模式" 的Microsoft文档http://www.microsoft.com/en-us/download/details.aspx?id=19957,它有以下摘录推荐同样的模式.

TaskCompletionSource <TResult>没有非泛型对应物.但是,Task <TResult>派生自Task,因此通用TaskCompletionSource <TResult>可以用于I/O绑定方法,它只使用带有虚拟TResult的源返回Task(布尔值是一个很好的默认选择,并且如果开发人员担心任务的消费者将其向下转发到Task <TResult>,则可以使用私有TResult类型)

  • 如果只接受`void`作为类型参数,则不需要进行这些扭曲. (26认同)
  • 考虑TaskCompletionSource <System.Reactive.Unit>以使读者更清楚. (7认同)
  • @RichB有趣.我之前没有见过那个令我惊讶的课程,如果我和下一个人不知道这意味着什么,那真的更清楚了吗?<wink>虽然好的建议. (3认同)
  • Scala:http://www.scala-lang.org/api/current/index.html#scala.Unit F#:http://msdn.microsoft.com/zh-cn/library/dd483472.aspx Wikipedia:https: //en.wikipedia.org/wiki/Unit_type我认为它比多余的布尔值或对象更清晰,即使它会使读者阅读上述文档也是如此。 (3认同)
  • `object`比`bool`的好处(如斯蒂芬的答案)是`bool`可能暗示有意义. (2认同)

Ste*_*ary 45

如果您不想泄露信息,通常的方法是使用TaskCompletionSource<object>并完成结果null.然后把它作为一个返回Task.


Dre*_*kes 16

.NET 5 有一个非通用的TaskCompletionSource.

它被添加到这个拉取请求中:https : //github.com/dotnet/runtime/pull/37452/files#diff-4a72dcb26e2d643c337baef9f64312f3