首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从TimerCallback函数Windows 8更新UI线程

从TimerCallback函数Windows 8更新UI线程
EN

Stack Overflow用户
提问于 2013-03-20 16:15:53
回答 1查看 3.4K关注 0票数 1

在这里有点困惑。

我有一个TimerCallback,它每10秒发射一次,其中包含要放到地图上的Geopoints。我尝试从计时器回调函数中将这些添加到映射中,但是由于它位于不同的线程中,所以我无法这样做。我收到以下错误:

“System.IO.FileNotFoundException”类型的异常发生在mscorlib.ni.dll中,在托管/本机边界之前没有处理。 System.UnauthorizedAccessException类型的第一次例外发生在System.Windows.ni.dll中

我怎么才能避开这一切呢?我认为可能添加一个NotifyCollectionChanged侦听器可以工作,但是我仍然有同样的问题。代码如下所示。

代码语言:javascript
复制
    private ObservableCollection<Bus> _busList;
    private Timer _timer = null;
    public ItemViewModel route;

    public ObservableCollection<Bus> BusList
    {
        get { return _busList; }
        set { _busList = value; }
    }
    //public LocationManager locMan = LocationManager.Instance;
    // Constructor
    public DetailsPage()
    {
        InitializeComponent();

        // Sample code to localize the ApplicationBar
        //BuildLocalizedApplicationBar();
    }

    // When page is navigated to set data context to selected item in list
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        route = null;
        if (DataContext == null)
        {
            string selectedIndex = "";
            if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
            {
                int index = int.Parse(selectedIndex);
                DataContext = App.ViewModel.Items[index];
                route = App.ViewModel.Items[index];
                if (_timer == null)
                {
                    TimerCallback tcb = obtainJSON;
                    _timer = new Timer(tcb, route.RouteID, 0, 10000);
                }
                else
                {
                    _timer.Change(0, 10000);
                }
                if (BusList == null)
                {
                    BusList = new ObservableCollection<Bus>();
                }
                else
                {
                    BusList.Clear();
                }
                BusList.CollectionChanged += HandleBusAdded;
            }
        }
    }

    private void HandleBusAdded(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Reset)
        {
            Debug.WriteLine("Everything was cleared");
        }
        else
        {
            foreach (Bus item in e.NewItems)
            {
                Debug.WriteLine(item.vehicleID);
                Polygon polygon = new Polygon();
                polygon.Points.Add(new Point(0, 0));
                polygon.Points.Add(new Point(0, 75));
                polygon.Points.Add(new Point(25, 0));
                polygon.Fill = new SolidColorBrush(Colors.Blue);

                // Create a MapOverlay and add marker
                MapOverlay overlay = new MapOverlay();
                overlay.Content = polygon;
                overlay.GeoCoordinate = new GeoCoordinate(item.lat, item.lng);
                overlay.PositionOrigin = new Point(0.0, 1.0);
                MapLayer mapLayer = new MapLayer();
                mapLayer.Add(overlay);
                //mapView.Layers.Add(mapLayer);

                this.Dispatcher.BeginInvoke(() =>
                {
                    mapView.Layers.Add(mapLayer);
                });
            }
        }

    }

    public void obtainJSON(Object stateInfo)
    {

        string url = "http://xxx.xxx.xxx" + stateInfo.ToString();
        var client = new WebClient();
        client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Decrypt);
        client.DownloadStringAsync(new Uri(url));
    }

    public void Decrypt(Object sender, DownloadStringCompletedEventArgs e)
    {
        if (BusList.Count > 0)
        {
            BusList.Clear();
        }
        if (!e.Cancelled && e.Error == null)
        {
            var temp = new List<string>();
            string[] buses = e.Result.Split('\n');
            foreach (string bus in buses)
            {
                if (!string.IsNullOrWhiteSpace(bus) && !string.IsNullOrEmpty(bus))
                {
                    temp.Add(bus);
                }
            }
            foreach (string item in temp)
            {
                string[] busInfo = item.Split(',');
                Bus newBus = new Bus(busInfo[0], busInfo[1], busInfo[2]);
                BusList.Add(newBus);

            }

            // This is where I initially tried
            /*Polygon polygon = new Polygon();
            polygon.Points.Add(new Point(0, 0));
            polygon.Points.Add(new Point(0, 75));
            polygon.Points.Add(new Point(25, 0));
            polygon.Fill = new SolidColorBrush(Colors.Blue);

            // Enable marker to be tapped for location information
            // polygon.Tag = new GeoCoordinate(BusList[0].lat, BusList[0].lng);

            // Create a MapOverlay and add marker
            MapOverlay overlay = new MapOverlay();
            overlay.Content = polygon;
            overlay.GeoCoordinate = new GeoCoordinate(BusList[0].lat, BusList[0].lng);
            overlay.PositionOrigin = new Point(0.0, 1.0);
            MapLayer mapLayer = new MapLayer();
            mapLayer.Add(overlay);

            this.Dispatcher.BeginInvoke(() =>
            {
                mapView.Layers.Add(mapLayer);
            });*/
            Debug.WriteLine("Present buses " + BusList[0].vehicleID + ", " + BusList[1].vehicleID);
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-20 17:36:54

最简单的方法是将obtainJSON方法中发生的事情封装在一个匿名函数中,该函数被分派回UI线程:

代码语言:javascript
复制
public void obtainJSON(Object stateInfo)
{    
    Dispatcher.BeginInvoke(() => { 
        string url = "http://xxx.xxx.xxx" + stateInfo.ToString();
        var client = new WebClient();
        client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Decrypt);
        client.DownloadStringAsync(new Uri(url));
    });    
}

这将意味着一切都发生在UI线程上(无论是发出web请求,还是在WebClient执行时处理响应,都是对调用它的线程的回调),所以您不会更新从不同线程绑定到UI线程的对象。

您也可以尝试使用DispatcherTimer而不是线程。

您还应该注意处理糟糕的网络条件,在这种情况下,请求将在超过10秒之后超时,并且可能会运行多个请求--这对您来说可能是一个问题,也可能不是一个问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15529006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档