ソケットを介して接続されるハードウェアがありますが、
今、私はチェックボックスで示されているハードウェアが接続されているかどうかを5秒ごとに確認する必要があります
私は機能を実装しました:
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について調査し、学びましたが、それをコードに実装できませんでした。
Ui elememtは、1つのUIスレッドからのみアクセスできます。 CheckBoxにはUIスレッドが必要で、タイマーは別のスレッドで実行されます。 Dispatcherを使用する簡単なコード
if (client.Connected == true)
{
Dispatcher.Invoke(()=> {
// Code causing the exception or requires UI thread access
CheckBox.IsChecked =true;
});
}
OR
if (client.Connected == true)
{
Dispatcher.Invoke(new Action(()=> {
// Code causing the exception or requires UI thread access
CheckBox.IsChecked =true;
}));
}
エラーを受け取った場合An object reference is required for the non-static field, method, or property
その後、これを使用します
Application.Current.Dispatcher.Invoke(() =>
{
// Code causing the exception or requires UI thread access
});
何らかの理由でDispatcherを使用したくない場合は、SynchronizationContextを使用できます。それほど大きな違いはありませんが、WPF固有のクラスではないため、SynchronizationContextを使用する場合の罪悪感は軽減されます。
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);
}
これを試して:
System.Windows.Application.Current.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate
{
// Update UI component here
CheckBox.IsChecked = false;
});