2012-11-23 23 views
1

我正在使用WPF和C#製作應用程序。我想要做的是在按下按鈕之間在一段時間內在畫布上打印大量形狀。在我按下按鈕的時候,一切都立即彈出。我已經嘗試在每個「打印」之間休息一段時間,但這並沒有幫助,只需要一段時間才能立即啓動。我想要的是,形狀每次彈出一個,讓我們說0.5秒。代碼如下:定期打印形狀

private void Create_Click(object sender, RoutedEventArgs e) 
    { 
     Random random = new Random(); 
     for (int i = 0; i < 50; i++) 
     { 
      Thread.Sleep(500); 
      Path f = FlowerFactory.createFlower(FlowerBP, true); 
      Canvas.SetLeft(f, random.Next(0, 1650)); 
      Canvas.SetTop(f, random.Next(0,1000)); 
      DrawBoard.Children.Add(f); 
     }} 

回答

3

您需要,第一,運行循環在後臺線程,以便它不會阻止更新UI;其次,將UI渲染任務發送回UI線程。對於第一個,你可以使用Task.Factory.StartNew,併爲第二,使用Dispatcher.Invoke

Random random = new Random(); 
Task.Factory.StartNew(() => 
{ 
    for (int i = 0; i < 50; i++) 
    { 
     Thread.Sleep(500); 
     Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => 
     { 
      Path f = FlowerFactory.createFlower(FlowerBP, true); 
      Canvas.SetLeft(f, random.Next(0, 1650)); 
      Canvas.SetTop(f, random.Next(0,1000)); 
      DrawBoard.Children.Add(f); 
     })); 
    } 
}); 
+1

最好的,只是做了:)我不是很用=>使用,但我會考慮它(拉姆達?)。非常感謝 – Abris

+0

不錯的解決方案,但Task Library是Framework 4.5的一部分。同時可以單獨包含它。 – RredCat

+1

@RredCat我認爲你的意思是4.0 ...我從來沒有在4.5,我可以使用它。也許你正在考慮異步/等待的東西,這是4.5? – McGarnagle

1

這是錯誤的決定睡你的主線程負責圖形用戶界面,。

嘗試使用DispatchTimer。例如:

DispatcherTimer m_dispatcherTimer = new DispatcherTimer(); 
int m_count = 50; 

private void Init() 
{ 
    m_dispatcherTimer.Tick += new EventHandler(OnTick); 
    m_dispatcherTimer.Interval = new TimeSpan(0, 0, 1); 
} 

private void Create_Click(object sender, RoutedEventArgs e) 
{ 
    m_count = 50; 
    m_dispatcherTimer.Start(); 
} 

private void OnTick(object sender, EventArgs e) 
{ 
    // Draw your shapes here 

    if(0>=--m_count) 
    { 
     m_dispatcherTimer.Stop(); 
    } 
} 
+0

它工作正常,但我更喜歡dBasemans解決方案,因爲它讓我在這種情況下保留我的for循環,但我可以想象我將在稍後使用此解決方案。謝謝! :) – Abris

+0

@Abris你是對的。 dBasemans解決方案看起來更加優雅。 – RredCat

0
using System.Reactive.Concurrency; 
using System.Reactive.Linq; 
... 
var subscription = Observable.Interval(TimeSpan.FromSeconds(0.5)).Take(50).Subscribe(x=>CreateRandomFlower);