2012-03-26 59 views
1

我正在爲我的遊戲寫一個戰士一代頁面。當戰士從服務器上下載時,該頁面應該用隨機化的值更新UI的強度和其他屬性。多個異步調用UI線程來更新文本塊

到目前爲止的代碼:

public partial class FighterGenerationPage : PhoneApplicationPage 
{ 
    Fighter fighter = null; 
    string Code = ""; 
    BackgroundWorker worker; 

    public FighterGenerationPage() 
    { 
     InitializeComponent(); 

     Loaded += new RoutedEventHandler(FighterGenerationPage_Loaded); 

     worker = new BackgroundWorker(); 
     worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
    } 

    void FighterGenerationPage_Loaded(object sender, RoutedEventArgs e) 
    { 
     AddFighter(); 
    } 

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) 
    { 
     NavigationContext.QueryString.TryGetValue("code", out Code); 

     if ("".Equals(Code)) 
      if (NavigationService.CanGoBack) 
       NavigationService.GoBack(); 

     base.OnNavigatedTo(e); 
    } 

    private void AddFighter() 
    { 
     WebProxy.GetInstance().AddFighter(AddFighter_Handler, Code); 
     worker.RunWorkerAsync(); 
    } 

    void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Random rand = new Random(); 
     while (fighter == null) 
     { 
      int strength = rand.Next(100); 
      Dispatcher.BeginInvoke(() => { StrValue.Text = Convert.ToString(strength); }); 
      Thread.Sleep(100); 
     } 

     Dispatcher.BeginInvoke(() => { StrValue.Text = Convert.ToString(fighter.Strength); }); 
    } 

    public void AddFighter_Handler(Response response) 
    { 
     #if DEBUG 
     Thread.Sleep(3000); 
     #endif 

     if (response.Status.Error == false) 
     { 
      fighter = response.Fighter; 
     } 
    } 
} 

此代碼幾乎做我想做的,但不是更新UI每0.1秒它做它在啓動一次,然後多次將其設置之前它到最後的價值(戰士。強度)。

爲什麼會這樣?

回答

0

我認爲正在發生的事情是這樣的:

  1. 您正在調試,這意味着你的AddFighter_Handler() Thread.sleep代碼的代碼被執行運行。

  2. 對AddFighter的調用會很快恢復。

  3. 當你在AddFighterHandler中使用Thread.Sleep()時,實際上是阻塞了用戶線程,因此從未實際調用傳遞給BeginInvoke的代碼。

這裏是你可以做,以解決這個問題最簡單的事情:

public void AddFighter_Handler(Response response) 
{ 
    System.Threading.ThreadPool.QueueUserWorkItem(o => { 
    #if DEBUG 
    Thread.Sleep(3000); 
    #endif 

    if (response.Status.Error == false) 
    { 
     fighter = response.Fighter; 
    }}); 
} 

這將確保你不會阻塞線程。

它也可能不是正確的事情 - 考慮使用DispatcherTimer得到類似的東西你暫停正在努力實現..

+0

啊哈,沒意識到AddFighter_Handler會得到同一個線程上執行.AddFighter(AddFighter_Handler,Code)調用。謝謝! – softarn 2012-03-26 21:39:31