3 回答
TA贡献1752条经验 获得超4个赞
如果你有一件不寻常的事情await,那么最简单的答案往往是TaskCompletionSource(或者是一些async基于原始的原语TaskCompletionSource)。
在这种情况下,您的需求非常简单,因此您可以直接使用TaskCompletionSource:
private TaskCompletionSource<object> continueClicked;private async void Button_Click_1(object sender, RoutedEventArgs e) {
// Note: You probably want to disable this button while "in progress" so the
// user can't click it twice.
await GetResults();
// And re-enable the button here, possibly in a finally block.}private async Task GetResults(){
// Do lot of complex stuff that takes a long time
// (e.g. contact some web services)
// Wait for the user to click Continue.
continueClicked = new TaskCompletionSource<object>();
buttonContinue.Visibility = Visibility.Visible;
await continueClicked.Task;
buttonContinue.Visibility = Visibility.Collapsed;
// More work...}private void buttonContinue_Click(object sender, RoutedEventArgs e){
if (continueClicked != null)
continueClicked.TrySetResult(null);}逻辑上,TaskCompletionSource就像一个async ManualResetEvent,除了你只能“设置”事件一次,事件可以有一个“结果”(在这种情况下,我们没有使用它,所以我们只是设置结果null)。
TA贡献1802条经验 获得超4个赞
这是我使用的实用程序类:
public class AsyncEventListener
{
private readonly Func<bool> _predicate;
public AsyncEventListener() : this(() => true)
{
}
public AsyncEventListener(Func<bool> predicate)
{
_predicate = predicate;
Successfully = new Task(() => { });
}
public void Listen(object sender, EventArgs eventArgs)
{
if (!Successfully.IsCompleted && _predicate.Invoke())
{
Successfully.RunSynchronously();
}
}
public Task Successfully { get; }
}
以下是我如何使用它:
var itChanged = new AsyncEventListener();
someObject.PropertyChanged += itChanged.Listen;
// ... make it change ...
await itChanged.Successfully;
someObject.PropertyChanged -= itChanged.Listen;
- 3 回答
- 0 关注
- 521 浏览
添加回答
举报
