我已经阅读了很多与BackgroundWorker和DispatcherTimer相关的SO问题,并了解您无法访问主线程以外的任何线程上的UI组件。
所以我有DispatcherTimer每1/2秒滴答一次。正如您所料,我可以更新视图模型类和任何需要直接操作的UI元素,并且UI非常敏感。但是我根据UI上的值进行计算,运行大约需要3秒。
我尝试在DispatcherTimer线程中进行调用,并锁定/阻止UI直到完成。目前我在DispatcherTimer中检查然后触发BackgroundWorker线程以进行计算。我使用e.Arguments将我需要的数据传递给我的3秒计算过程,并使用e.Result获取我收到的已完成数据。
我检查了结果,没有生成错误。然而,当我将e.Result投回到我的班级时,e.Result无法正确评估。当我来使用类属性时,我基本上得到了“调用线程无法访问错误”。
...
timerBackgroundLoop = new DispatcherTimer(DispatcherPriority.Background);
timerBackgroundLoop.Interval = TimeSpan.FromMilliseconds(500);
timerBackgroundLoop.Tick += new EventHandler(Timer_Tick);
timerBackgroundLoop.Start();
...
private void Timer_Tick(object sender, EventArgs e)
{
if (MyClass.NeedToRebuildBuildMap)
{
MyClass.NeedToRebuildBuildMap = false; //stop next timer tick from getting here
threadDrawMap = new BackgroundWorker();
threadDrawMap.WorkerReportsProgress = false;
threadDrawMap.WorkerSupportsCancellation = false;
threadDrawMap.DoWork += new DoWorkEventHandler(threadDrawMap_DoWork);
threadDrawMap.RunWorkerCompleted += new RunWorkerCompletedEventHandler(threadDrawMap_Completed);
threadDrawMap.RunWorkerAsync(myClass.MapData);
}
...
}
private void threadDrawMap_DoWork(object sender, DoWorkEventArgs e)
{
MyClass.MapData _mapData = (MyClass.MapData)e.Argument;
e.Result = BuildMap(_mapData);
}
private void threadDrawMap_Completed(object sender, RunWorkerCompletedEventArgs e)
{
MyClass.MapGeo = (List<PathGeometry>)e.Result;
DrawUIMap(MyClass.MapGeo); //draws the map on the UI into a grid
}
当我在“threadDrawMap_Completed”中设置一个中断并评估PathGeometry的List时,我得到这个错误:base {System.SystemException} = {“调用线程无法访问此对象,因为另一个线程拥有它。”}
直到我进入DrawUIMap方法并尝试访问MyClass.MapGeo几何列表时,我才真正看到错误。此时我回到了DispatcherTimer线程,该线程可以访问UI。
据我所知,我已经完成了所有操作,只要我访问UI组件的位置。虽然我认为我在某处做了一些可怕的错误。
**编辑: 这是执行计算的代码的一部分
public static List<PathGeometry> BuildMap(List<PathGeometry> _geoList)
{
...
List<PathGeometry> retGeoList = new List<PathGeometry>();
retGeoList.Add(geoPath1);
retGeoList.Add(geoPath2);
...
return retGeoList;
}