2012-03-26 60 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