C# 调用线程无法访问此对象,因为另一个线程拥有它,即WPF
我有一个通过插座连接的硬件 现在我必须每隔5秒检查一次硬件是否已连接,并通过复选框显示 我实现了一个功能:C# 调用线程无法访问此对象,因为另一个线程拥有它,即WPF,c#,wpf,multithreading,C#,Wpf,Multithreading,我有一个通过插座连接的硬件 现在我必须每隔5秒检查一次硬件是否已连接,并通过复选框显示 我实现了一个功能: private static System.Timers.Timer aTimer; public MainWindow() { InitializeComponent(); client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); aTimer = new System.T
private static System.Timers.Timer aTimer;
public MainWindow()
{
InitializeComponent();
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
aTimer = new System.Timers.Timer();
aTimer.AutoReset = true;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000;
aTimer.Enabled = true;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
if (client.Connected == true)
{
Console.WriteLine("Not Connected");
CheckBox.IsChecked = false;
}
else
{
Console.WriteLine("Connected");
CheckBox.IsChecked = false;
}
}
但当我运行应用程序时,它抛出了错误
调用线程无法访问此对象,因为其他线程拥有它。
我研究并了解了Dispatcher.Invoke,但无法在代码中实现它。尝试以下方法:
System.Windows.Application.Current.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate
{
// Update UI component here
CheckBox.IsChecked = false;
});
ui元素只能由一个ui线程访问。复选框需要UI线程,并且计时器在不同的线程上运行。使用Dispatcher的简单代码
if (client.Connected == true)
{
Dispatcher.Invoke(()=> {
// Code causing the exception or requires UI thread access
CheckBox.IsChecked =true;
});
}
或
如果收到错误非静态字段、方法或属性需要对象引用,请使用此
Application.Current.Dispatcher.Invoke(() =>
{
// Code causing the exception or requires UI thread access
});
如果出于某种原因不想使用Dispatcher,可以使用SynchronizationContext。虽然没有太大区别,但使用SynchronizationContext时我感觉不那么内疚,因为它不是特定于WPF的类:
private static System.Timers.Timer aTimer;
private SynchronizationContext _uiContext = SynchronizationContext.Current;
public MainWindow()
{
InitializeComponent();
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
aTimer = new System.Timers.Timer();
aTimer.AutoReset = true;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000;
aTimer.Enabled = true;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
_uiContext.Post(new SendOrPostCallback(new Action<object>(o => {
if (client.Connected == true)
{
Console.WriteLine("Not Connected");
CheckBox.IsChecked = false;
}
else
{
Console.WriteLine("Connected");
CheckBox.IsChecked = false;
}
})), null);
}
private static System.Timers.Timer aTimer;
私有同步上下文_uiContext=SynchronizationContext.Current;
公共主窗口()
{
初始化组件();
BeginConnect(remoteEP,新的异步回调(ConnectCallback),client);
aTimer=新的System.Timers.Timer();
aTimer.AutoReset=true;
aTimer.Appead+=新的ElapsedEventHandler(OnTimedEvent);
a时间间隔=2000;
aTimer.Enabled=true;
}
私有void OnTimedEvent(对象源,ElapsedEventArgs e)
{
_uiContext.Post(新的SendOrPostCallback(新操作)(o=>{
if(client.Connected==true)
{
控制台。写入线(“未连接”);
CheckBox.IsChecked=false;
}
其他的
{
控制台。写入线(“连接”);
CheckBox.IsChecked=false;
}
})),空);
}
Duad Khan:上面的示例给了我一个错误:无法将Lambda表达式转换为“System.delegate”,因为它不是我所做编辑的委托类型检查。有关此错误的详细信息:()完美男人。。非常感谢!!:):DGreat@Fayilt您的代码对我来说很好:):)这有帮助,而其他一切都失败了。看不出它是如何工作的。上述代码中的参数顺序不正确。@dotNET:它在与调度程序关联的线程上以指定的优先级同步执行指定的线程。可能您正期待调用方法的另一个重载。上述代码中的参数顺序完全正确,请参见msdn:
private static System.Timers.Timer aTimer;
private SynchronizationContext _uiContext = SynchronizationContext.Current;
public MainWindow()
{
InitializeComponent();
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
aTimer = new System.Timers.Timer();
aTimer.AutoReset = true;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000;
aTimer.Enabled = true;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
_uiContext.Post(new SendOrPostCallback(new Action<object>(o => {
if (client.Connected == true)
{
Console.WriteLine("Not Connected");
CheckBox.IsChecked = false;
}
else
{
Console.WriteLine("Connected");
CheckBox.IsChecked = false;
}
})), null);
}