【发布时间】:2017-06-30 06:35:47
【问题描述】:
通常我会检查我是否可以访问ObservableCollection,如果没有,我会调用Dispatcher。这里(Stackoverflow)还有其他一些解决方案,但我不知道什么是最好和最干净的方法。我认为我的解决方案已过时,不应再使用。
在我的示例中,ItemsCollection 绑定到 UI。将调用_UpdateTheCollectionFromAnotherThread()(从另一个thread 或打开另一个thread)并将数据临时保存到items。之后我会检查访问权限并在需要时拨打dispatcher。
这是我必须走的路还是有更好更清洁的解决方案?
FooClass
public class FooClass
{
// ##############################################################################################################################
// Properties
// ##############################################################################################################################
/// <summary>
/// This Items are bound to my UI.
/// </summary>
public ObservableCollection<string> ItemsCollection { get; } = new ObservableCollection<string>();
// ##############################################################################################################################
// Singleton pattern
// ##############################################################################################################################
/// <summary>
/// The instance of <see cref="FooClass"/>.
/// </summary>
internal static FooClass Instance => _Instance ?? (_Instance = new FooClass());
private static FooClass _Instance;
// ##############################################################################################################################
// Konstruktor
// ##############################################################################################################################
private FooClass()
{
}
// ##############################################################################################################################
// Method
// ##############################################################################################################################
private void _UpdateTheCollectionFromAnotherThread()
{
List<string> items = new List<string>();
//Here would be some logic to create and fill the items list....
//and now apply them to the public list
if (System.Windows.Application.Current.Dispatcher.CheckAccess())
{
ItemsCollection.Clear();
foreach (string item in items)
{
ItemsCollection.Add(item);
}
}
else
{
System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
ItemsCollection.Clear();
foreach (string item in items)
{
ItemsCollection.Add(item);
}
}));
}
}
}
【问题讨论】:
-
I think my solution is obsolete and should not be used anymore.为什么?你有问题吗?如果有,请列举它们。如果没有,就没有理由改变。我们不可能找到比已经满足您要求的解决方案更好的解决方案 -
您可以编写它更干净,而无需复制更新集合的代码
-
我能补充的就是让这个工作为你的测试工作,检查调度程序是否为空。
public class RootDispatcherFetcher {private static Dispatcher _rootDispatcher = null;public static Dispatcher RootDispatcher{ get { _rootDispatcher = _rootDispatcher ?? Application.Current != null ? Application.Current.Dispatcher : new Dispatcher(...); return _rootDispatcher;} // unit tests can get access to this via InternalsVisibleTo internal set { _rootDispatcher = value; } } } -
这个解决方案怎么样? jonathanantoine.com/2011/09/24/… 使用
BindingOperations.EnableCollectionSynchronization()?
标签: c# wpf multithreading observablecollection dispatcher