2014-01-23 66 views
14

我已被通過插座相連接的硬件,因爲不同的線程擁有它調用線程不能訪問該對象,WPF

現在我必須檢查硬件在其被示出每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但是我不能在我的代碼中實現它。

回答

25

的UI elememt只能由一個UI線程訪問。 CheckBox需要UI線程,並且您的計時器在不同的線程上運行。簡單的代碼使用調度

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 
}); 
+0

Duad Khan:上面的示例給出了我錯誤: 無法將Lambda表達式轉換爲'System.delegate',因爲它不是委託類型 –

+1

檢查我編輯的編輯。有關此錯誤的更多信息:(http://stackoverflow.com/questions/9549358/cannot-convert-lambda-expression-to-type-system-delegate) –

+0

完美的人.. 謝謝噸! :):D –

2

試試這個:

System.Windows.Application.Current.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate 
{ 
    // Update UI component here 
    CheckBox.IsChecked = false; 
}); 
+1

這有所幫助,而其他一切都失敗了。 – IneedHelp

+0

看不到它是如何工作的。上述代碼中參數的順序不正確。 – dotNET

+0

@dotNET:它在Dispatcher所關聯的線程上以指定的優先級同步執行指定的線程。可能是你期待另一個Invoke方法的重載。參數的順序在上面的代碼中是絕對正確的,參見msdn:https://msdn.microsoft.com/en-us/library/ms591593(v=vs.110).aspx – Ramashankar

5

如果你不想使用調度出於某種原因,你可以使用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); 
} 
+0

很棒@Fayilt 你的代碼適合我:) :) :) –

相關問題