問題 - WPF 不支持從調度程序線程以外的線程對其 SourceCollection 進行的更改

[問題] WPF 不支持從調度程序線程以外的線程對其 SourceCollection 進行的更改

有一次要在其中一個執行緒中改變 ObservableCollection 型別的項目時出錯了

問題描述 :

編譯時跳出了 不支持從調度程序線程以外的線程對其 SourceCollection 進行的更改 的錯誤,此 ObservableCollection 類型是屬於 UI 控件的 SourceCollection,所以不支持另外的執行緒對其進行更改

解決問題 :

使用 Dispatcher 就能解決

  • Dispatcher

    • WPF 中大部分的控件都繼承自 DispatcherObject
    • 而 WPF 中 DispatcherObject 只能透過與他關聯的 Dispatcher 進行訪問
    • 使用 Dispatcher 有兩種方法 : Invoke ( 同步 )、InvokeAsync ( 非同步 )
1
2
3
4
Application.Current?.Dispatcher.InvokeAsync(() =>
{
MyObservableCollection.Add("This string is add by other Task");
});
  • 舊的 BeginInvoke 與新的 InvokeAsync

    • .NET Framework 4.5 開始,新增了 InvokeAsync
    • 現在 BeginInvoke 其實也早已經改為使用 TAP(Task-based Asynchronous Pattern ) 模式
    • 所以基本上 InvokeAsync 現在跟 BeginInvoke 一樣,所以使用新的 InvokeAsync 就好
tags: 問題 WPF C# 多執行緒 Dispatcher
Author: Kenny Li
Link: https://kennyliblog.nctu.me/2021/01/16/WPF-other-Thread-problem/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.