所以我是计时器和线程的新手,我无法找到如何制作一个调用编辑/修改MainWindow控件的函数的计时器。
Xaml代码:
<Window x:Class="TimerTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox Height="287" HorizontalAlignment="Left" Margin="12,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="479" />
</Grid>
</Window>
C#代码:
namespace TimerTest
{
public partial class MainWindow : Window
{
//Declaring my aTimer as global
public static System.Timers.Timer aTimer;
//Function that is called
public void OnTimedEvent(object source, ElapsedEventArgs e)
{
textBox1.Text += "SomeText ";
}
public MainWindow()
{
InitializeComponent();
aTimer = new Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 1000; // every 5 seconds
aTimer.Enabled = true;
}
}
}
我得到的错误: “调用线程无法访问此对象,因为另一个线程拥有它。” P.S。:另外我对代表不太好,所以如果你认为在这种情况下可以帮助我,那么请发一个代码样本。
答案 0 :(得分:13)
只需添加:
aTimer.SynchronizingObject = this;
创建计时器后,或使用ToolBox-&gt;组件中的OTHER类型的计时器,即System.Windows.Forms.Timer。
您正在使用的计时器触发线程池线程而不是UI线程,因此需要与UI线程同步以按您希望的方式工作。
答案 1 :(得分:4)
只允许与某个控件关联的线程修改该控件。
要从其他线程修改控件,您需要将更新代码包装在delegate
中并将其传递给textBox1.Dispatcher.BeginInvoke
:
namespace TimerTest
{
public partial class MainWindow : Window
{
private delegate void updateDelegate(string text);
private void updateTextBox(string text)
{
textBox1.Text += text;
}
//Declaring my aTimer as global
public static System.Timers.Timer aTimer;
//Function that is called
public void OnTimedEvent(object source, ElapsedEventArgs e)
{
textBox1.Dispatcher.BeginInvoke(
new updateDelegate(updateTextBox), "SomeText ");
}
public MainWindow()
{
InitializeComponent();
aTimer = new Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 1000; // every 5 seconds
aTimer.Enabled = true;
}
}
}
答案 2 :(得分:1)
问题是您正在尝试从其他线程更新UI线程。在WinForms中,您必须将回调编组回UI线程。
按照WPF .NET Best way to trigger an event every minute中的示例,在WPF中,您可以使用Dispatcher Timer:
public static System.Windows.Threading.DispatcherTimer aTimer;
public WindowUpdatedByTimer()
{
InitializeComponent();
aTimer = new System.Windows.Threading.DispatcherTimer();
aTimer.Tick += new EventHandler(OnTimedEvent);
aTimer.Interval = TimeSpan.FromSeconds(5);
aTimer.Start();
}
public void OnTimedEvent(object source, EventArgs e)
{
textBox1.Text += "SomeText ";
}