簡體   English   中英

對UI線程的多個異步調用以更新文本塊

[英]Multiple async calls to UI thread to update textblock

我正在為游戲編寫戰斗機生成頁面。 當從服務器下載戰斗機時,該頁面應該使用強度和其他屬性的隨機值更新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;
        }
    }
}

這段代碼幾乎可以完成我想要的操作,但是不是每隔0.1秒更新一次UI,而是在啟動時執行一次,然后在將其設置為最終值(fighter.Strength)之前執行多次。

為什么會這樣呢?

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

  1. 您正在Debug中運行,這意味着將執行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來獲得您想要實現的類似暫停效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM