3 回答

TA貢獻(xiàn)1752條經(jīng)驗(yàn) 獲得超4個(gè)贊
如果你有一件不尋常的事情await
,那么最簡(jiǎn)單的答案往往是TaskCompletionSource
(或者是一些async
基于原始的原語(yǔ)TaskCompletionSource
)。
在這種情況下,您的需求非常簡(jiǎn)單,因此您可以直接使用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
就像一個(gè)async
ManualResetEvent
,除了你只能“設(shè)置”事件一次,事件可以有一個(gè)“結(jié)果”(在這種情況下,我們沒(méi)有使用它,所以我們只是設(shè)置結(jié)果null
)。

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超4個(gè)贊
這是我使用的實(shí)用程序類:
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 關(guān)注
- 486 瀏覽
添加回答
舉報(bào)