private async void CheckProduct(object sender, EventArgs e)
{
try
{
// Only permit one lookup at a time
productCheckButton.Enabled = false;
statusLabel.Text = "Checking...";
nameValue.Text = "";
priceValue.Text = "";
stockValue.Text = "";
string id = idInput.Text;
Task<Product> productLookup = directory.LookupProductAsync(id);
Task<int> stockLookup = warehouse.LookupStockLevelAsync(id);
Product product = await productLookup;
if (product == null)
{
statusLabel.Text = "Product not found";
// We don't care about the result of the stock check
return;
}
nameValue.Text = product.Name;
priceValue.Text = product.Price.ToString("c");
int stock = await stockLookup;
stockValue.Text = stock.ToString();
statusLabel.Text = "Ready";
}
finally
{
// However we finish this method, allow another lookup
productCheckButton.Enabled = true;
}
}
}
c#5 特性:可以中断代码的执行,但不阻塞线程
产品和库存查找是异步的
在等待结果时,并没有真正阻塞UI线程 即使代码在UI线程里
线程从他离开的地方继续执行
没有任何启动线程的 /BackgroundWorker, 调用Control.BeginInvoke 或对异步事件附加 回调函数
async/await 去掉了模板代码。
public async Task<Product> LookupProductAsync(string productId)
{
await Task.Delay(Math.Abs(productId.GetHashCode() % 4000));
return Products.FirstOrDefault(p => p.Id == productId);
}
输入
private static readonly List<Product> Products = new List<Product>
{
new Product(id: "WS", name: "West Side Story", price: 9.99m),
new Product(id: "AS", name: "Assassins", price: 14.99m),
new Product(id: "FR", name: "Frogs", price: 13.99m),
new Product(id: "ST", name: "Sweeney Todd", price: 10.99m),
};
输出