我正在开发一个应用程序,它将(作为其功能的一小部分)提供倒数计时器。但是,可能并且将会出现同时发生多次倒计时的情况。每个Count Down在枢轴视图中都有自己的枢轴项。由于这些倒计时是动态创建的,我将每个倒计时的文本块(用作剩余时间的输出)添加到列表中,并且我设置了一个计时器来调用循环遍历每个文本块的方法在列表中并相应地更新它们。但是,我收到了“System.UnauthorizedAccessException”的异常,但我不完全确定原因。我被告知这是“无效的跨线程访问”的错误。
以下是违规行:
c.Label.Dispatcher.BeginInvoke(delegate() { c.Label.Text = timeRemaining; });
以下是完整的方法:
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; });
}
}
}
以下是我创建计时器的方法,这是提到CallBack的唯一时间:
Timer updateRemainingTime = new Timer(TimeRemainingCallback, null, 0, 1000);
列表中充满了包含日期时间和文本块的对象(此处称为标签),因此是c.Label交易。
timeRemaining是timercallback中剩余时间的字符串。
关于这里发生了什么的任何想法?关于如何做到这一点的任何更好的想法?
答案 0 :(得分:1)
为整个循环迭代调用Dispatcher
,并删除当前的Dispatcher调用。
Dispatcher.BeginInvoke(() =>
{
foreach (CountDown c in countDowns)
{
// Actions here.
c.Label.Text = timeRemaining;
}
});
我假设您已countDowns
绑定到您正在使用的列表UI控件。