我需要访问TimerData.textSet字段来更改控制时间的另一个线程显示的文本。但是抛出了InvalidOperationException。有没有解决这个问题的方法。
namespace Scilca.KBL
{
public class TimerData
{
public Run textSet;
public ProgressBar statusTimer;
public TimerData(Run run, ProgressBar statusTimer)
{
textSet = run;
this.statusTimer = statusTimer;
}
}
/// <summary>
/// Interaction logic for KBLSessionWindow.xaml
/// </summary>
public partial class KBLSessionWindow : Window
{
private int leftTime = 60;
private static Run run;
private static ProgressBar progressBar;
public int TimeLeftOver
{
get { return leftTime; }
}
public KBLSessionWindow()
{
InitializeComponent();
run = runSecondTime;
progressBar = timeProgress;
Thread timerThread = new Thread(new ParameterizedThreadStart(startTimer));
timerThread.Start(new TimerData(run, progressBar));
}
public void startTimer(Object td)
{
TimerData timerData = (TimerData)td;
int time = 60;
while (true)
{
Thread.Sleep(1000);
time -= 1;
if (time == 0)
time = 60;
Console.WriteLine(timerData.textSet.Text);
timerData.textSet.Text = time.ToString(); // InvalidOperationException
timerData.statusTimer.Value = time * 100 / 60;
}
}
}
}
答案 0 :(得分:0)
看起来您正在尝试从非ui线程访问UI元素。
每当您从主线程以外的线程更新UI元素时,您需要使用:
Application.Current.Dispatcher.Invoke(() =>
{
// your code here.
timerData.textSet.Text = time.ToString();
timerData.statusTimer.Value = time * 100 / 60;
});
否则您将获得System.InvalidOperationException
来自MSDN:
当对象的状态不支持方法调用时调用对象的方法时,抛出System.InvalidOperationException。当方法尝试从不是主线程或UI线程的线程操作UI时,也会抛出异常。
与您的问题无关,我建议使用计时器(见下文),而不是每次都创建一个新的线程,这会因为Timer使用线程池而更有效:
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent);
myTimer.Interval = 1000; // 1000 ms is one second
myTimer.Start();
public static void DisplayTimeEvent(object source, ElapsedEventArgs e)
{
// code here will run every second
}