通常我會推薦一個像這樣的函數來執行暫停,同時允許UI進行交互。
private void InteractivePause(TimeSpan length)
{
DateTime start = DateTime.Now;
TimeSpan restTime = new TimeSpan(200000); // 20 milliseconds
while(true)
{
System.Windows.Forms.Application.DoEvents();
TimeSpan remainingTime = start.Add(length).Subtract(DateTime.Now);
if (remainingTime > restTime)
{
System.Diagnostics.Debug.WriteLine(string.Format("1: {0}", remainingTime));
// Wait an insignificant amount of time so that the
// CPU usage doesn't hit the roof while we wait.
System.Threading.Thread.Sleep(restTime);
}
else
{
System.Diagnostics.Debug.WriteLine(string.Format("2: {0}", remainingTime));
if (remainingTime.Ticks > 0)
System.Threading.Thread.Sleep(remainingTime);
break;
}
}
}
但似乎是在使用時從事件處理程序中調用此類解決方案的一些併發症,如按鈕點擊。我認爲系統希望按鈕單擊事件處理程序在它將繼續處理其他事件之前返回,因爲如果我在事件處理程序仍在運行時嘗試再次單擊,則該按鈕會再次按下,即使我試圖拖動窗體而不是點擊按鈕。
所以這裏是我的選擇。在表單上添加一個計時器,並創建一個經銷商類以處理與該計時器交互的卡片。設置定時器的Interval屬性以匹配您想要發送卡片的時間間隔。這是我的示例代碼。
public partial class Form1 : Form
{
CardDealer dealer;
public Form1()
{
InitializeComponent();
dealer = new CardDealer(timer1);
}
private void button1_Click(object sender, EventArgs e)
{
dealer.QueueCard(img1, cardImage1);
dealer.QueueCard(img2, cardImage2);
dealer.QueueCard(img3, cardImage1);
}
}
class CardDealer
{
// A queue of pairs in which the first value represents
// the slot where the card will go, and the second is
// a reference to the image that will appear there.
Queue<KeyValuePair<Label, Image>> cardsToDeal;
System.Windows.Forms.Timer dealTimer;
public CardDealer(System.Windows.Forms.Timer dealTimer)
{
cardsToDeal = new Queue<KeyValuePair<Label, Image>>();
dealTimer.Tick += new EventHandler(dealTimer_Tick);
this.dealTimer = dealTimer;
}
void dealTimer_Tick(object sender, EventArgs e)
{
KeyValuePair<Label, Image> cardInfo = cardInfo = cardsToDeal.Dequeue();
cardInfo.Key.Image = cardInfo.Value;
if (cardsToDeal.Count <= 0)
dealTimer.Enabled = false;
}
public void QueueCard(Label slot, Image card)
{
cardsToDeal.Enqueue(new KeyValuePair<Label, Image>(slot, card));
dealTimer.Enabled = true;
}
}
謝謝,代表很棒!另外,我從來沒有把實際的交易調用放入計時器的時間週期中(我只是在做一個計數++類型的場景),這在將來可能會有用! – Windos
正如我所解釋的,只是在計時器中執行'count ++'將無濟於事,因爲while循環中的代碼仍然會阻塞UI線程。 – SLaks
順便說一句,它也可能誤用迭代器來做到這一點;如果你有興趣,我會解釋。 – SLaks