- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在进行异步调用,最终将更新 GUI 中的集合。异步调用是通过这样的委托(delegate)命令完成的:
StartDoingUsefulStuffCommand = new DelegateCommand(() => Task.Run(() => StartDoingUsefulStuff()));
public async Task StartDoingUsefulStuff()
{
try
{
await some method
do something else
MyCollection.Clear();
...
...
}
catch (Exception e)
{
// handle exception
}
}
最终 StartDoingUsefulStuff 方法想要更新一个集合,导致这个异常,因为另一个线程试图更新一个集合:
A first chance exception of type 'System.NotSupportedException' occurred in PresentationFramework.dll
Additional information: This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
我找到了一个解决方案:在当前 SynchronizationContext 中运行任务:
Task.Factory.StartNew(() => StartDoingUsefulStuff(), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
这会很好地工作,但对我来说,每次从 XAML 调用命令时都执行所有这些操作似乎很乏味。您对我目前的解决方案有何看法/最佳做法是什么?
最佳答案
还有一种更简单的修复方法。在初始化 Collection 的构造函数中,只需在初始化后添加以下行。
BindingOperations.EnableCollectionSynchronization(MyCollection,_lock);
其中 _lock
是一个私有(private)静态对象
。那时您不必再在命令中处理线程安全问题。然后您可以安全地使用 await Task.Run
。
关于c# - 确保异步方法可以更新非线程安全集合的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20210793/
我是一名优秀的程序员,十分优秀!