我遇到了一些與任務和異步/等待關鍵字混淆。我知道你不應該混用異步和阻止代碼。或者至少我對混合它們的解釋是:等待/異步任務不等待
不要調用阻塞來自非異步方法的API。所以這是我的問題。
我想等待一個方法,然後相應地更新用戶界面。問題在於等待異步方法()調用的唯一方法是從async方法和async方法中調用。
下面是一個例子:
private RelayCommand<Options> _executeCommand;
public RelayCommand<Options> ExecuteCommand
{
get
{
return _executeCommand ?? (_executeCommand = new RelayCommand<Options>(async (options) =>
{
Completed = false;
var cancellationTokenSource = new CancellationTokenSource();
await RunValidation(options, cancellationTokenSource.Token);
Completed = true;
}));
}
}
此代碼正常運行的方法和等待。問題出在我回來的時候。出於某種原因,設置完成標誌時,取決於此標誌的按鈕不會切換。如果我評論等待代碼,那麼按鈕將正確切換。所以,假設我沒有返回UI線程上,所以我嘗試使用此代碼來代替:
private RelayCommand<Options> _executeCommand;
public RelayCommand<Options> ExecuteCommand
{
get
{
return _executeCommand ?? (_executeCommand = new RelayCommand<Options>(async (options) =>
{
Completed = false;
var cancellationTokenSource = new CancellationTokenSource();
var context = TaskScheduler.FromCurrentSynchronizationContext();
await RunValidation(options, cancellationTokenSource.Token).ContinueWith(t => Completed = true, context);
//Completed = true;
}));
}
}
這裏是RunValidation()方法:
private async Task RunValidation(Options options, CancellationToken token)
{
await _someService.SomAsyncMethod(options, token));
}
如果你注意到,在ExecuteCommand具有異步在傳遞給命令的(選項)參數之前的關鍵字。如果我刪除了異步關鍵字,那麼我必須修改對RunValidation()方法的調用。我仍然需要它等待,所以這就是我所做的:
private RelayCommand<Options> _executeCommand;
public RelayCommand<Options> ExecuteCommand
{
get
{
return _executeCommand ?? (_executeCommand = new RelayCommand<Options>((options) =>
{
Completed = false;
var context = TaskScheduler.FromCurrentSynchronizationContext();
var cancellationTokenSource = new CancellationTokenSource();
Task.Run(async() => await RunValidation(options, cancellationTokenSource.Token));
Completed = true;
}));
}
}
此代碼的問題是它不會等待。所以我很茫然。
任何人都可以在這裏爲我闡明一些東西。我已經花了兩天多的時間,而我仍然在這裏。
感謝, 添
這裏是綁定命令按鈕。
private readonly Independent<bool> _completed = new Independent<bool>(true);
public bool Completed
{
get { return _completed; }
set { _completed.Value = value; }
}
private ICommand _doneCommand;
public ICommand DoneCommand
{
get
{
return _doneCommand ?? (_doneCommand = MakeCommand.When(() => Completed).Do(() =>
{
DoSomething();
}));
}
}
private ICommand _cancelCommand;
public ICommand CancelCommand
{
get
{
return _cancelCommand ??
(_cancelCommand = MakeCommand.When(() => !Completed).Do(() => DoSomthingElse()));
}
}
我使用來自Michael Perry的UpdateControls庫中的MakeCommand對象。它們包含依賴性跟蹤,在完成屬性更改時引發CanExecuteChange事件。
第一個代碼塊是正確的。這些按鈕如何綁定到完成標誌?它是否可觀察? – Jason
由於您的問題是由於通知丟失,因爲你正在使用應提高您通知您一個圖書館,我建議你提出問題與UpdateControls庫。 –
所以我不瘋狂,從事物的外觀,我正確地做事情? – user953710