0

.NET 4.0 を使用して、csv ファイルを解析し、データの各行をオブジェクト化し、WCF コールバックを介してクライアントに型として返すホスト アプリケーションを作成しました。この部分は正常に動作します。問題が発生し始めるのは、その型または型のコレクションを MainWindow の ObservableCollection に追加しようとしたときです。

したがって、この...

 public class MyServiceCallback : IMyServiceCallback
    {
        //List<Location.LocationData> lastData = new List<Location.LocationData>();
        //Dictionary<string, Location.LocationData> lastData = new Dictionary<string,Location.LocationData>();
        //Network exposed Callback method which recieves Host/Client common data type
        //Note: Ought to be an interface and not a class type, but not needed for a small project
        public void OnCallback(Location.LocationData[] t)
        {
            //if(t.Where(x=>x.Frequency == lastData[
            //foreach (Location.LocationData d in t)
            //{
            //    lastData.Add(d.Frequency, d);
            //}
            //Call static method on MainWindow to pass the collection of LocationData to UI bound LocationList
            if(!(t.Length == 0))
            Client.MainWindow.SetLocationList(t.ToList());            
        }
    }

WCF ホストから呼び出され、 SetLocation(t.ToList()) がこれを呼び出します...

public partial class MainWindow : Window
    {

private static MTObservableCollection<Location.LocationData> locationList = new MTObservableCollection<Location.LocationData>();

public static MTObservableCollection<Location.LocationData> LocationList
{
     get { return locationList; }
     set { locationList = value; }
} 

public static void SetLocationList(List<Location.LocationData> hostPushedLocationData)
        {
            //Clear previous location data
            LocationList.Clear();

            System.Threading.Thread.SpinWait(1);

            //Add the pushed data to the bound collection to be displayed
            hostPushedLocationData.ForEach(data => { LocationList.Add(data); System.Threading.Thread.SpinWait(1); });

        }
}

プレーンな ObservableCollection を使用していた場合、WCF スレッドからコレクションを更新できないため、これはまったく機能しません。

これでObservableCollectionを拡張すると...

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);
                }
        }

    }

私はここで見つけました:スレッドセーフな CollectionView はどこで入手できますか?

断続的に次のエラーが発生します。

このバージョンを使用すると例外が発生しますが、Jonathan から提供されたバージョンを使用すると発生しません。なぜこれが起こっているのか誰にも考えがありますか?ここに私の InnerException があります: コントロール 'System.Windows.Controls.DataGrid Items.Count:3' のジェネレーター 'OrdersGrid' が、アイテムの現在の状態と一致しない一連の CollectionChanged イベントを受け取ったため、この例外がスローされましたコレクション。次の違いが検出されました: 累積カウント 2 は実際のカウント 3 とは異なります。 [累積カウントは (最後のリセット時のカウント + #追加 - #最後のリセット以降の削除)

リンクされた投稿で言及されています。

また、より頻繁に、次のエラーが発生しました: インデックスが範囲外でした。

この問題を解決するために、このコレクション拡張機能に対して何をする必要があるかについて、誰かが私を助けたり、正しい方向に向けたりすることができれば、私はそれを大いに感謝します. また、4.0 の代わりに .NET 4.5 を使用すると、この問題は軽減されますか?

ありがとうございます!

4

1 に答える 1

0

コレクションの変更イベントをDispatcher.BeginInvoke(). コレクションは、イベントをスケジュールしてから実際にイベントが発生するまでの間に数回変更される場合があります。例外メッセージに基づいて、これがまさに起こっていることのようです。

変更イベントが後で発生するようにスケジュールしないでください。それらはすぐに引き上げられることを意図しています。

于 2013-11-04T21:02:37.583 に答える