ในแอปรถไฟใต้ดิน C # / XAML ของฉันมีปุ่มที่เริ่มกระบวนการทำงานที่ยาวนาน ดังนั้นตามที่แนะนำฉันใช้ async / รอคอยเพื่อให้แน่ใจว่าเธรด UI ไม่ถูกบล็อก:
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
await GetResults();
}
private async Task GetResults()
{
// Do lot of complex stuff that takes a long time
// (e.g. contact some web services)
...
}
บางครั้งสิ่งที่เกิดขึ้นภายใน GetResults จะต้องป้อนข้อมูลผู้ใช้เพิ่มเติมก่อนจึงจะสามารถดำเนินการต่อได้ เพื่อความง่ายสมมติว่าผู้ใช้เพียงคลิกปุ่ม "ดำเนินการต่อ"
คำถามของฉันคือฉันจะระงับการใช้งาน GetResults ในลักษณะที่รอเหตุการณ์เช่นการคลิกปุ่มอื่นได้อย่างไร
นี่เป็นวิธีที่น่าเกลียดที่จะบรรลุสิ่งที่ฉันกำลังมองหา: ตัวจัดการเหตุการณ์สำหรับปุ่มดำเนินการต่อ "ตั้งค่าสถานะ ...
private bool _continue = false;
private void buttonContinue_Click(object sender, RoutedEventArgs e)
{
_continue = true;
}
... และ GetResults ทำการสำรวจความคิดเห็นเป็นระยะ:
buttonContinue.Visibility = Visibility.Visible;
while (!_continue) await Task.Delay(100); // poll _continue every 100ms
buttonContinue.Visibility = Visibility.Collapsed;
โพลนั้นแย่มาก (การรอคอย / เสียรอบ) และฉันกำลังมองหาบางสิ่งที่อิงกับเหตุการณ์
ความคิดใด ๆ
Btw ในตัวอย่างที่เข้าใจง่ายนี้มีวิธีแก้ปัญหาหนึ่งที่แน่นอนว่าจะแบ่ง GetResults () ออกเป็นสองส่วนเรียกส่วนแรกจากปุ่มเริ่มต้นและส่วนที่สองจากปุ่มดำเนินการต่อ ในความเป็นจริงสิ่งที่เกิดขึ้นใน GetResults นั้นมีความซับซ้อนมากขึ้นและการป้อนข้อมูลผู้ใช้ประเภทต่างๆสามารถทำได้ในจุดต่าง ๆ ภายในการดำเนินการ ดังนั้นการแบ่งตรรกะออกเป็นหลาย ๆ วิธีจะไม่ไร้สาระ
ManualResetEvent(Slim)
WaitAsync()