我在 C# 中遇到了 async/await 的問題,我需要它來獲取一些名為 Trades 的物件,在我得到它之后,它需要保存它。問題是,使用 async/await,它首先進行 SAVE,然后去獲取我的交易物件。我如何確保首先獲得物件,然后進行保存....這是我的代碼...
private async void OnRefresh()
{
try
{
var trades = await ExchangeServiceInstance.GetTrades("");
mmTrades = new ObservableCollection<EEtrade>(trades);
tradeListView.ItemsSource = mmTrades;
}
catch { }
}
public async void OnSignalReceived()
{
// THIS NEEDS TO FINISH FIRST, BUT IT DOESN'T
await tradeListView.Dispatcher.InvokeAsync((Action)async delegate
{
if (ExchangeServiceInstance.SelectedTabIndex == CURRENT_TAB_INDEX_ITEM)
{
await Task.Delay(MMConfig.DELAYMILLISEC);
OnRefresh();
}
});
// SOMEHOW THIS GETS CALLED FIRST BEFORE THE ABOVE GETS TO FINISH!
await OnSaveTrades();
}
public async Task<int> OnSaveTrades()
{
foreach (var trade in mmTrades)
{
await ExchangeServiceInstance.OnInsertDoneTrade(trade);
}
return mmTrades.Count;
}
有什么想法嗎?謝謝!
uj5u.com熱心網友回復:
問題是你的OnRefresh方法。因為回傳型別是void不等待的方法[查看這個答案]。此外,您甚至都不會嘗試等待委托中的方法
將方法更改為以下內容:
private async Task OnRefresh()
{
try
{
var trades = await ExchangeServiceInstance.GetTrades("");
mmTrades = new ObservableCollection<EEtrade>(trades);
tradeListView.ItemsSource = mmTrades;
}
catch { }
}
并在您的委托中等待此方法,應該可以解決您的問題:
public async void OnSignalReceived()
{
// THIS NEEDS TO FINISH FIRST, BUT IT DOESN'T
await tradeListView.Dispatcher.InvokeAsync((Action)async delegate
{
if (ExchangeServiceInstance.SelectedTabIndex == CURRENT_TAB_INDEX_ITEM)
{
await Task.Delay(MMConfig.DELAYMILLISEC);
await OnRefresh();
}
});
// SOMEHOW THIS GETS CALLED FIRST BEFORE THE ABOVE GETS TO FINISH!
await OnSaveTrades();
}
uj5u.com熱心網友回復:
的用法與(Action)async基本相同async void,而且async void幾乎總是一個錯誤。具體來說,消費者無法知道結果(除非它同步出錯)。這里的調度員并沒有真正考慮async。
如果我們假設您必須在這里使用調度程式,也許一種解決方法可能是使用類似 a SemaphoreSlim(或者也許 a )的東西,您在異步作業結束TaskCompletionSource<something>時發出信號(即使在例外情況下),然后等待它;未經測驗,但是:
var tcs = new TaskCompletionSource<bool>();
await tradeListView.Dispatcher.InvokeAsync((Action)async delegate
{
try {
if (ExchangeServiceInstance.SelectedTabIndex == CURRENT_TAB_INDEX_ITEM)
{
await Task.Delay(MMConfig.DELAYMILLISEC);
OnRefresh();
}
tcs.TrySetResult(true);
} catch (Exception ex) {
tcs.TrySetException(ex);
}
});
await tcs.Task; // ensure the async work is complete
await OnSaveTrades();
uj5u.com熱心網友回復:
首先,您經常使用 async void 模式。出于多種原因,這確實是一種不好的做法。你應該停止這樣做。
這里的問題是,這OnRefresh又是一個不能等待但應該是的異步 void 方法:
private async Task OnRefresh()
{
try
{
var trades = await ExchangeServiceInstance.GetTrades("");
mmTrades = new ObservableCollection<EEtrade>(trades);
tradeListView.ItemsSource = mmTrades;
}
catch { }
}
在您的OnSignalReceived方法中將呼叫更改OnRefresh();為await OnRefresh();
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/521347.html
下一篇:WPF如何移動GUI系結
