เธรดการเปลี่ยนสลีปใน. NET สำหรับ Windows Store


98

Thread.Sleepดูเหมือนจะไม่รองรับในแอพ. NET สำหรับ Windows Store

ตัวอย่างเช่นนี้

System.Threading.Thread.Sleep(1000);

จะคอมไพล์เมื่อกำหนดเป้าหมาย. NET Framework ใด ๆ (2.0, 3.5, 4.0, 4.5) แต่ไม่ใช่เมื่อกำหนดเป้าหมาย. NET สำหรับแอป Windows Store (หรือในไลบรารีคลาสแบบพกพาซึ่งกำหนดเป้าหมายทั้ง 4.5 และที่จัดเก็บ)

System.Threading ยังคงมีเธรดอยู่ แต่ก็ไม่มีเมธอด Sleep

ฉันต้องการหน่วงเวลาบางอย่างในแอปของฉันสักสองสามวินาทีมีการทดแทนที่เหมาะสมหรือไม่

แก้ไขสาเหตุที่จำเป็นต้องมีการหน่วงเวลา: แอปของฉันเป็นเกมและความล่าช้าคือการทำให้ดูเหมือนว่าฝ่ายตรงข้ามคอมพิวเตอร์กำลัง "คิด" เกี่ยวกับการเคลื่อนไหวครั้งต่อไปของเขา วิธีนี้เรียกว่าแบบอะซิงโครนัสแล้ว (เธรดหลักไม่ได้ถูกบล็อก) ฉันแค่ต้องการชะลอเวลาตอบสนอง


2
การพิจารณาว่าแอพ Windows Store ไม่ควรที่จะหยุด UI (ทุกอย่างควรจะเป็นแบบ async) ทำให้รู้สึกว่าไม่รองรับ
Sruly

2
คุณมีกิจกรรมหรือMonitorชั้นเรียนหรือไม่? คุณสามารถใช้Waitวิธีนี้ด้วยการหมดเวลาเพื่อจำลองการนอนหลับ
ทิวดอร์

นี่คือ Apptivate.ms หรือไม่ : 3
EaterOfCode

3
ใช่สำหรับการเนรเทศThread.Sleepไปที่ถังขยะของเทคโนโลยีที่ไม่ดี
ผู้ใช้จ่าย

คำตอบ:


203

ร้านค้าของ Windows ปพลิเคชัน asynchrony อ้อมกอด - และ "หยุดไม่ตรงกัน" Task.Delayให้บริการโดย ดังนั้นภายในวิธีการอะซิงโครนัสคุณจะต้องเขียน:

await Task.Delay(TimeSpan.FromSeconds(30));

... หรืออะไรก็ได้ที่คุณต้องการ วิธีการอะซิงโครนัสจะดำเนินต่อไปใน 30 วินาทีต่อมา แต่เธรดจะไม่ถูกบล็อกเช่นเดียวกับawaitนิพจน์ทั้งหมด


1
น่าเสียดายที่ Task.Delay ดูเหมือนจะไม่ได้รับการสนับสนุนเมื่อกำหนดเป้าหมาย. NET 4.5 + store + WP7 ในไลบรารีคลาสแบบพกพา .. ฉันเดาว่าฉันจะย้ายสิ่งนี้ไปยังคลาสเฉพาะของแพลตฟอร์ม
สูงสุด

1
@Max: ไม่เพราะไม่เคยมีมาก่อน. NET 4.5 IIRC, WP7 เองไม่มีการรองรับ TPL (ฉันอาจจะผิด ... )
Jon Skeet

4
คุณสามารถจัดการได้.RunSynchronously()หากจำเป็น
HappyNomad

1
@RAM: ดีThread.Sleep จะได้รับการสนับสนุนใน NET 3.5 ดังนั้นคำถามไม่ได้ใช้ ไม่สงสัยคุณมีคำถาม แต่มันก็ไม่ได้เสียงเหมือนมันเป็นเช่นเดียวกับคนนี้ โปรดอ่านtinyurl.com/stack-hintsแล้วถามคำถามใหม่
Jon Skeet

2
@RAM: ฉันไม่แน่ใจว่าฉันตั้งใจจะเดาสิ่งนั้นจากความคิดเห็นของคุณอย่างไร มีคำถามที่คล้ายกันมากมายเกี่ยวกับ SO เกี่ยวกับ WPF และแอนิเมชั่น
Jon Skeet


20

ฉันเพิ่งมีปัญหาเดียวกันและพบวิธีแก้ปัญหาที่น่าสนใจอีกวิธีหนึ่งที่ฉันต้องการแบ่งปันกับคุณ ถ้าคุณต้องการบล็อกเธรดจริงๆฉันจะทำเช่นนี้ (ขอบคุณ @Brannon สำหรับคำใบ้ "บาง"):

// `waitHandle.Set` is never called, so we wait always until the timeout occurs
using (var waitHandle = new ManualResetEventSlim(initialState: false))
{
    waitHandle.Wait(TimeSpan.FromSeconds(5));
}

นี่คือคำตอบที่ดีที่สุดสำหรับการเข้ารหัสแบบพกพา
zezba9000

ใช้รุ่น "บาง" นี้
Brannon

11

MainPage.xaml.cs

public MainPage()
{
  this.InitializeComponent();
  this.WaitForFiveSeconds();
}

private async void WaitForFiveSeconds()
{
  await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(5));
  // do something after 5 seconds!
}

-7

มีเกือบจะไม่มีเหตุผล (ยกเว้นเพื่อวัตถุประสงค์ในการทดสอบ) Thread.Sleep()เพื่อการใช้งานที่เคย

IF (และเฉพาะในกรณีที่) คุณมีเหตุผลที่ดีมากในการส่งเธรดเข้าสู่โหมดสลีปคุณอาจต้องการตรวจสอบTask.Delay()ซึ่งคุณสามารถรอเพื่อ "รอ" ตามเวลาที่กำหนด แม้ว่าจะไม่ควรมีด้ายนั่งเฉยๆและไม่ทำอะไรเลย ปฏิบัติไม่ดี ...


9
ฉันไม่เห็นด้วย. หากเธรดเป็นเธรดพื้นหลังและการสลีปสั้นการตั้งเวลาสลีปจะมีประสิทธิภาพมากกว่าการใช้ไทม์เมอร์
Jason Steele

1
และบางครั้งคุณได้รับคำสั่งให้ทำแม้ว่าจะให้คำแนะนำแก่ผู้มีอำนาจในผลที่ตามมาก็ตาม)
จอร์แดน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.