5

新しい要素を受け取ったときに Event を発生させるサービスに登録し、この要素を に追加しBlockingCollectionます。監視可能なコレクション内の要素を追加/更新するために
ループする 2 番目のスレッドを実行しています。BlockingCollection

問題は、どのように ? を追加するObservableCollectionかです。.addUI スレッドで実行する必要があるため、このタイプのコレクションでは実行できないことはわかっています。そのため、ディスパッチャーを使用して要素の追加をマーシャリングする別ObservableCollectionのサブクラスを使用しようとしましたが、毎回同じエラーが発生します

「タイプ 'System.StackOverflowException' の未処理の例外が不明なモジュールで発生しました。」

トラブルシューティングのヒントは次のとおりです。

無限ループや無限再帰がないことを確認してください。

BlockingQueue1 秒あたり 5 から 10 のように、常に新しい要素を受信して​​いるため、実際にはある種の無限ループがあります。ただし、コントロールをにバインドしない場合、または代わりにリストを使用する場合
、例外は発生しません。observablecollection

Class ElementHolder
{
    private ExternalService _externalService;
    private ObservableCollection<Element> _elementsList = new ObservableCollection<Element>();
    private BlockingCollection<Element> _elementsReceived = new BlockingCollection<Element>();

    public ObservableCollection<Element> ElementsList
    {
        get
        {
            return _elementList;
        }
        set
        {
            _elementList = value;
        }
    }

public ElementHolder()
    {
        Task.Factory.StartNew(ReadElements);
        _externalService = new ExternalService();
        _externalService.ReceivedNewElement += new Action<Element>(o => _elementsReceived.Add(o));
        _externalService.Subscribe();
    }

private void ReadElements()
    {
        foreach (Element element in _elementsReceived.GetConsumingEnumerable())
        {
            Element item = _elementsList.FirstOrDefault(o => o.ID == element.ID);
            if (item == null)
            {
                _elementList.Add(element);
            }
            else
            {
                item.Update(element);
            }
        }
    }

編集バグを追跡していると、バグは自然に消えました。問題がどこにあるのかを本当に理解するために、物事を単純化しようとしていましたが、それが機能し始めました. 物事を元に戻すと、まだ機能します...しかし、リストビューにスタイルを追加するなどの無関係な理由で、時々戻ってきます。サードパーティの dll に問題があるのではないかと考え始めています。

4

2 に答える 2

3

これは、Reactive Extensions が非常に便利で独創的なツールであることを示す完璧な例です。それらを使用するにはかなり急な学習曲線がありますが、ここには特定のケースがあるため、目標を正しく理解していると仮定して、目標を達成するリアクティブ コードを挿入します。

Reactive Extensions をインストールする必要があり、2 つの using ステートメント (System.Reactive.Linq と System.Reactive.Subjects) が必要であり、System.Reactive と System.Reactive.Windows.Threading dll を参照する必要があることに注意してください。MSDN のリアクティブを参照してください。

class ElementHolder
{
    public ObservableCollection<Element> ElementsList { get; set; }
    private ExternalService _externalService = new ExternalService();
    private IDisposable _elementSubscription;
    private Subject<Element> _elementSubject = new Subject<Element>();

    public ElementHolder()
    {
        _externalService.ReceivedNewElement += _elementSubject.OnNext;
        _externalService.Subscribe();

        ElementList = new ObservableCollection<Element>();
        _elementSubscription = _externalService.ObserveOnDispatcher().Subscribe(NextElement);
    }

    private void NextElement(Element e)
    {
        Element item = ElementsList.FirstOrDefault(o => o.ID == element.ID);
        if (item == null) {
            _elementList.Add(element);
        }
        else {
            item.Update(element);
        }
    }
}
于 2012-11-05T15:08:12.707 に答える
0

答えに小さな誤りがあります。以下の修正された行を参照してください。

_elementSubscription = _elementSubject.ObserveOnDispatcher().Subscribe(NextElement);

これを理解するのにしばらく時間がかかりましたが、rmayer06 の答えが私の問題を解決しました。答えについてコメントすることはできません。

于 2013-02-24T20:44:14.000 に答える