赞
踩
实际项目中,应用到了线程运作:
如采集一个数据调用CatchDataByDay方法:
Task.Run(() => CatchDataByDay());
虽然利用代码2,判断数据是否重复。意图只保存不重复数据。但仍出现重复现象。
- private ObservableCollection<Race> _RaceCollect;
- public ObservableCollection<Race> RaceCollect //用于保存数据的集合,并向UI通知更新
- {
- get { return this._RaceCollect; }
- set
- {
- this._RaceCollect = value;
- RaisePropertyChanged(() => RaceCollect);
- }
- }
- private void CatchDataByDay()
- {
- //此处省无关代码。
-
- string rsp = _http.HttpGet(url);
-
- JavaScriptSerializer serializer = new JavaScriptSerializer();
- var raceObject = serializer.Deserialize<Raceobject>(rsp);
- DataItem[] datas = raceObject.result.data;
- int n;
- for (int i = datas.Length - 1; i >= 0; i--)
- {
- var a = datas[i];
-
- //判断是否存在该数据
- if (ListContains(a.preDrawIssue)) continue;
- //
- Race race = new Race();
-
- //此处省无关代码。
-
- lock (locker)
- {
- _dispatcher.Invoke(new Action(() =>{_RaceCollect.Add(race);}));
-
- PickNumbersFromCollection();//挑选顺序出现的数字,并判断是否达到10个
- }
-
- }
- }//day
- //此处省无关代码。
- }
- //判断集合中是否存在该数据
- private bool ListContains(string qh)
- {
- lock (locker)
- {
- var races = _RaceCollect.ToList<Race>();
- var ar = (from x in races where (x.QH.ToString().Trim() == qh.Trim()) select x).ToArray();
- if (ar == null || ar.Count() == 0)
- return false;
- else return true;
- }
- // 异常:System.ArgumentException: 目标数组的长度不够。请检查 destIndex 和长度以及数组的下限
- // 原因:List<T> 集合不是线程安全的,在并发操作 List 时,内部计算可能会出现问题
-
- }
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Threading;
-
- namespace Airship
- {
- /// <summary>
- /// 线程安全的集合,将ObservableCollection替换掉即可
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public class AsyncObservableCollection<T> : ObservableCollection<T>
- {
- //获取当前线程的SynchronizationContext对象
- private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
- public AsyncObservableCollection() { }
- public AsyncObservableCollection(IEnumerable<T> list) : base(list) { }
- protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
- {
-
- if (SynchronizationContext.Current == _synchronizationContext)
- {
- //如果操作发生在同一个线程中,不需要进行跨线程执行
- RaiseCollectionChanged(e);
- }
- else
- {
- //如果不是发生在同一个线程中
- //准确说来,这里是在一个非UI线程中,需要进行UI的更新所进行的操作
- _synchronizationContext.Post(RaiseCollectionChanged, e);
- }
- }
- private void RaiseCollectionChanged(object param)
- {
- // 执行
- base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
- }
- protected override void OnPropertyChanged(PropertyChangedEventArgs e)
- {
- if (SynchronizationContext.Current == _synchronizationContext)
- {
- // Execute the PropertyChanged event on the current thread
- RaisePropertyChanged(e);
- }
- else
- {
- // Post the PropertyChanged event on the creator thread
- _synchronizationContext.Post(RaisePropertyChanged, e);
- }
- }
- private void RaisePropertyChanged(object param)
- {
- // We are in the creator thread, call the base implementation directly
- base.OnPropertyChanged((PropertyChangedEventArgs)param);
- }
- }
- }
2。替代2
- /// <summary>
- /// 如何使的 ObservableCollection 线程安全的?(How to make ObservableCollection thread-safe?)
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public class MTObservableCollection<T> : ObservableCollection<T>
- {
- public override event NotifyCollectionChangedEventHandler CollectionChanged;
- protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
- {
- NotifyCollectionChangedEventHandler CollectionChanged = this.CollectionChanged;
-
- if (CollectionChanged != null)
- foreach (NotifyCollectionChangedEventHandler nh in CollectionChanged.GetInvocationList())
- {
- DispatcherObject dispObj = nh.Target as DispatcherObject;
- if (dispObj != null)
- {
- Dispatcher dispatcher = dispObj.Dispatcher;
- if (dispatcher != null && !dispatcher.CheckAccess())
- {
- dispatcher.BeginInvoke(
- (Action)(() => nh.Invoke(this,
- new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
- DispatcherPriority.DataBind);
- continue;
- }
- }
- nh.Invoke(this, e);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。