2014-04-28 30 views
6

Possiedo un'applicazione che contiene un elenco di oggetti memorizzati in un pacchetto simultaneo statico.Alternativa concurrentBag nella libreria di classi portatili

L'interfaccia utente dispone di un timer che corre metodi che possono aggiornare gli oggetti nel ConcurrentBag.

solo thread (avviata dal timer) tenterà di aggiornare questi oggetti. Tuttavia questo thread enumererà l'elenco e quindi aggiornerà gli elementi man mano che procede.

Allo stesso tempo questi oggetti possono essere letti dal thread UI.

ConcurrentBag è perfettamente funzionante per quello che voglio fare. Tutta la logica di business è in un progetto separato e ora devo trasferire tutto su IOS e Android. Lo sto facendo con Xamarin e sto convertendo la logica di business in una libreria di classi portatili.

Anche se tutto quello che sto mira sembra sostenere ConcurrentBag, quando provo ad accedere in un PCL, System.Collections.Concurrent non è disponibile. Anche se scelgo solo .net 4.5 e versioni successive + windows store apps (Entrambi ho usato ConcurrentBags per)

Se esiste un'altra alternativa a ConcurrentBag o sto meglio creando solo progetti separati per ciascun sistema di destinazione?

+0

Quale versione VS sono stai usando e quali target PCL scegli? Se per esempio seleziono * .NET 4 *, * Windows (App Store) 8 *, * Xamarin.Android * e * Xamarin.iOS * in VS2013 Update 2RC, posso utilizzare con successo 'ConcurrentBag' nel mio codice. Finché non scegli come target * Windows Phone * o * Silverlight *, penso che non dovresti avere problemi nell'utilizzare 'ConcurrentBag' nel tuo PCL. –

+0

Grazie Anders. Sono attualmente sull'aggiornamento 1, quindi sto scaricando l'aggiornamento 2 ora per vedere se è d'aiuto. Sono tutte le versioni di Win Phone che non funzioneranno? – Oli

+0

Ho appena controllato; Lo spazio dei nomi 'System.Collections.Concurrent' è * non * incluso in qualsiasi versione di WP, incluso 8.1. A proposito, sembra strano che tu non possa accedere a "ConcurrentBag" su VS 2013 Update 1 a patto di evitare i target WP/Silverlight? Hai ricontrollato che non funziona sull'Aggiornamento 1 anche quando scegli come target .NET 4, Windows (Store) 8, Xamarin.Android e Xamarin.iOS? –

risposta

1

Beh, se l'ovvio non funziona, sono disponibili diverse opzioni qui. Primo, decompilare ConcurrentBag e usare quel codice. Secondo, è trovare un sostituto. E 'la mia stima che nel tuo caso specifico non è necessariamente bisogno delle garanzie di prestazioni e problemi di ordine di un ConcurrentBag ... Quindi, questo è un esempio di lavoro di quello che sarebbe adatta al vostro conto:

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"; 
               } 
              } 
             }); 
     } 
    } 
} 
Problemi correlati