2014-04-28 14 views
6

Mam aplikację, która ma listę obiektów przechowywanych w statycznej równoległej torbie.ConcurrentBag Alternative In Portable Class Library

Interfejs użytkownika ma licznik czasu, który uruchamia metody, które mogą aktualizować obiekty w aplikacji ConcurrentBag.

Tylko jeden wątek (Rozpoczęty przez zegar) będzie próbował zaktualizować te obiekty. Jednak ten wątek wyliczy listę, a następnie zaktualizuje elementy w toku.

W tym samym czasie te obiekty można odczytać za pomocą wątku interfejsu użytkownika.

ConcurrentBag działa idealnie na to, co chcę robić. Cała logika biznesowa jest w osobnym projekcie i muszę teraz przenieść wszystko na IOS i Androida. Robię to z Xamarinem i tak przekształcam logikę biznesową w Portable Class Library.

Mimo że wszystko, na co jestem ukierunkowany, wydaje się wspierać ConcurrentBag, gdy próbuję uzyskać do niego dostęp w PCL, System.Collections.Concurrent nie jest dostępny. Nawet jeśli kierujemy się tylko aplikacjami sklepu .net 4.5 i nowszymi + Windows (obie używałem ConcurrentBags do)

Jeśli istnieje inna alternatywa dla ConcurrentBag, czy lepiej dla mnie po prostu tworzyć osobne projekty dla każdego systemu docelowego?

+0

Której wersji VS są których używasz i jakie cele PCL wybierasz? Jeśli na przykład wybiorę * .NET 4 *, * Windows (aplikacje Store) 8 *, * Xamarin.Android * i * Xamarin.iOS * w VS2013 Update 2RC, mogę z powodzeniem zastosować 'ConcurrentBag' w moim kodzie. Dopóki nie celujesz w * Windows Phone * lub * Silverlight *, nie powinieneś mieć problemów z używaniem 'ConcurrentBag' w twoim PCL. –

+0

Dzięki Anders. Obecnie korzystam z Aktualizacji 1, więc teraz pobieram aktualizację 2, aby sprawdzić, czy to pomaga. Czy wszystkie wersje Win Phone nie będą działać? – Oli

+0

Właśnie sprawdziłem; Przestrzeń nazw 'System.Collections.Concurrent' jest * nie * zawarta w żadnej wersji WP, włączając w to 8.1. Przy okazji, wydaje się dziwne, że nie masz dostępu do 'ConcurrentBag' na VS 2013 Update 1, o ile unikasz celów WP/Silverlight? Czy sprawdziłeś dwukrotnie, czy nie działa on w aktualizacji 1, nawet gdy kierujesz się na .NET 4, Windows (Store) 8, Xamarin.Android i Xamarin.iOS? –

Odpowiedz

1

Cóż, jeśli oczywiste nie będzie działać, masz kilka opcji tutaj. Po pierwsze, należy dekompilować ConcurrentBag i użyć tego kodu. Po drugie, wymyślić zamiennik. To mój szacunek, że w konkretnym przypadku nie muszą gwarancji wydajności i problemy nakazująca ConcurrentBag ... Tak, to jest przykład roboczych, co pasuje do Twojego Bill:

namespace Naive 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 

    public class ThreadSafeCollectionNaive<T> 
    { 
     private readonly List<T> _list = new List<T>(); 
     private readonly object _criticalSection = new object(); 

     /// <summary> 
     /// This is consumed in the UI. This is O(N) 
     /// </summary> 
     public ReadOnlyCollection<T> GetContentsCopy() 
     { 
      lock (_criticalSection) 
      { 
       return new List<T>(_list).AsReadOnly(); 
      } 
     } 

     /// <summary> 
     /// This is a hacky way to handle updates, don't want to write lots of code 
     /// </summary> 
     public void Update(Action<List<T>> workToDoInTheList) 
     { 
      if (workToDoInTheList == null) throw new ArgumentNullException("workToDoInTheList"); 

      lock (_criticalSection) 
      { 
       workToDoInTheList.Invoke(_list); 
      } 
     } 

     public int Count 
     { 
      get 
      { 
       lock (_criticalSection) 
       { 
        return _list.Count; 
       } 
      } 
     } 

     // Add more members as you see fit 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var collectionNaive = new ThreadSafeCollectionNaive<string>(); 

      collectionNaive.Update((l) => l.AddRange(new []{"1", "2", "3"})); 

      collectionNaive.Update((l) => 
             { 
              for (int i = 0; i < l.Count; i++) 
              { 
               if (l[i] == "1") 
               { 
                l[i] = "15"; 
               } 
              } 
             }); 
     } 
    } 
} 
Powiązane problemy