开发者

Issue with updating a textblock in WP7 with a timer

开发者 https://www.devze.com 2023-03-25 15:04 出处:网络
I working on an app that will (as a minor subset of it\'s functionality) provide a countdown timer. However, there can and will be instances where there are multiple count downs going at the same time

I working on an app that will (as a minor subset of it's functionality) provide a countdown timer. However, there can and will be instances where there are multiple count downs going at the same time. Each Count Down has it's own pivot item in a pivot view. Since these countdowns are dynamically created, I'm adding the textblock (that serves as the output for the time remaining) for each countdown to a list, and I've set开发者_Python百科 a timer to call a method that cycles through each one of those textblocks in the list and update them accordingly. However, I'm receiving an exception of "System.UnauthorizedAccessException" but I'm not entirely sure why. I am being told it's a error of "Invalid cross-thread access."

Here's the line that is the offending line:

c.Label.Dispatcher.BeginInvoke(delegate() { c.Label.Text = timeRemaining; });

Here is the full method:

private static void TimeRemainingCallback(object state)
    {
        if (countDowns.Count == 0)
        {
            return;
        }

        foreach (CountDown c in countDowns)
        {
            DateTime rightNow = DateTime.Today;

            if (c.ExpirationDate >= rightNow)
            {
                DateTime offsetExpiration = c.ExpirationDate.Add(c.LocalNow);
                TimeSpan timeDifference = offsetExpiration.Subtract(rightNow);


                String timeRemaining = "";
                String timeDays = "";
                String timeHours = "";
                String timeMinutes = "";
                String timeSeconds = "";

                if (timeDifference.Days == 1)
                {
                    timeDays = "1 Day";
                }
                else
                {
                    timeDays = timeDifference.Days + " Days";
                }

                if (timeDifference.Hours == 1)
                {
                    timeHours = "1 Hour";
                }
                else
                {
                    timeHours = timeDifference.Hours + " Hours";
                }

                if (timeDifference.Minutes == 1)
                {
                    timeMinutes = "1 Minute";
                }
                else
                {
                    timeMinutes = timeDifference.Minutes + " Minutes";
                }

                if (timeDifference.Seconds == 1)
                {
                    timeSeconds = "1 Second";
                }
                else
                {
                    timeSeconds = timeDifference.Seconds + " Seconds";
                }

                if (timeDifference.Days == 0 && timeDifference.Hours >= 1)
                {
                    timeRemaining = timeHours + " " + timeMinutes;
                }
                else if (timeDifference.Days == 0 && timeDifference.Hours == 0 && timeDifference.Minutes >= 1)
                {
                    timeRemaining = timeMinutes + " " + timeSeconds;
                }
                else if (timeDifference.Days == 0 && timeDifference.Hours == 0 && timeDifference.Minutes == 0)
                {
                    timeRemaining = timeSeconds;
                }
                else
                {
                    timeRemaining = timeDays + " " + timeHours + " " + timeMinutes;
                }

                c.Label.Dispatcher.BeginInvoke(delegate() { c.Label.Text = timeRemaining; });
            }
        }
    }

Here is how I create the timer, the only time the CallBack is mentioned:

Timer updateRemainingTime = new Timer(TimeRemainingCallback, null, 0, 1000);

The list is really full of objects that contain a datetime and a textblock (which here is called label) thus the c.Label deal.

timeRemaining is the string of the time remaining that is formed in the timercallback.

Any ideas of what's going on here? Any better ideas on how to do this?


Invoke the Dispatcher for the entire loop iteration, and remove your current Dispatcher invocation.

Dispatcher.BeginInvoke(() =>
{
    foreach (CountDown c in countDowns)
    {
       // Actions here.
       c.Label.Text = timeRemaining;
    }
});

I am assuming you have countDowns bound to the list UI control you're working with.

0

精彩评论

暂无评论...
验证码 换一张
取 消