我是新手等待异步,我想了解我在这个真实场景中研究过的主题:
我有一个简单的代码,读取比特币价格,需要1-2秒,我不想使用等待异步锁定UI,如果加载或完成仍然给出状态:
private void button_Click(object sender, RoutedEventArgs e)
{
Task<int> bitcoinPriceTask = GetBitcoinPrice();
lblStatus.Content = "Loading...";
}
protected async Task<int> GetBitcoinPrice()
{
IPriceRetrieve bitcoin = new BitcoinPrice();
string price = bitcoin.GetStringPrice();
txtResult.Text = price;
lblStatus.Content = "Done";
return 1;
}
根据要求,这里是BitcoinPrice类的实现:
public class BitcoinPrice : IPriceRetrieve
{
public BitcoinPrice()
{
Url = "https://www.google.com/search?q=bitcoin%20price";
}
public string Url { get; }
public string GetStringPrice()
{
var html = RetrieveContent();
html = MetadataUtil.GetFromTags(html, "1 Bitcoin = ", " US dollars");
return html;
}
public float GetPrice()
{
throw new NotImplementedException();
}
public string RetrieveContent()
{
var request = WebRequest.Create(Url);
var response = request.GetResponse();
var dataStream = response.GetResponseStream();
var reader = new StreamReader(dataStream);
var responseFromServer = reader.ReadToEnd();
return responseFromServer;
}
}
答案 0 :(得分:7)
您的代码现在有很多问题,首先您需要将事件处理程序设置为async
,以便您可以等待返回Task<int>
的方法,其次可以设置消息加载之前调用方法并等待它,以便它等待该方法完成它,并在它完成工作返回结果时,然后将消息设置为完成:
private async void button_Click(object sender, RoutedEventArgs e)
{
lblStatus.Content = "Loading...";
int bitcoinPriceTask = await GetBitcoinPrice();
lblStatus.Content = "Done";
}
protected async Task<int> GetBitcoinPrice()
{
IPriceRetrieve bitcoin = new BitcoinPrice();
string price = await bitcoin.GetStringPrice();
txtResult.Text = price;
return 1;
}
或更好的可以返回Task<string>
并在事件处理程序中设置TextBox值:
protected async Task<string> GetBitcoinPrice()
{
IPriceRetrieve bitcoin = new BitcoinPrice();
string price = await bitcoin.GetStringPrice();
return price;
}
并在事件处理程序中:
private async void button_Click(object sender, RoutedEventArgs e)
{
lblStatus.Content = "Loading...";
string price = await GetBitcoinPrice();
txtResult.Text = price;
lblStatus.Content = "Done";
}