Oppure

Loading
31/05/09 15:09
Jeremy
Postato originariamente da GoLDBeRG:

ho un array di nome users (shared)

questo array è in continuo mutamento tra eliminazione e aggiunta di user.

ho bisogno di inviare un messaggio a tutti e 5000 gli utenti ma mentre il ciclo invia i messaggi a tutti entra un utente modifica l'array e il ciclo va a all'aceto..... cosa posso fare? non mi dite usa una var boolean perche ho centinaia di cicli... ci sarà pur qualcosa che mi permette di sapere se l'array è sotto ciclo o no?


Ciao.
Non ti serve sapere se è sotto ciclo o no
Come hai letto, puoi sfruttare Linq e produrre una cosa del genere
    Supponiamo che tu abbia un array di 5000 elementi
    Dim Users(4999) As String


    Private Sub CiclaArray()
        Dim myUsers = From _Users In Users Select _Users
        For Each User In myUsers
            MessageBox.Show(User)
        Next
    End Sub



In questo modo, essendo Users un array di String, per inferenza del tipo myUsers diventerà un IEnumerable(of String) completamente disconnesso dall'origine(Users) e quindi non soggetto a cambiamenti durante il ciclo.

Facci sapere...
Ciao
Ultima modifica effettuata da Jeremy 01/06/09 13:47
aaa
31/05/09 15:45
Jeremy
In allegato una piccola dimostrazione.

Facci sapere...
Ciao
aaa
01/06/09 8:20
Il Totem
Jeremy, quel codice non genera alcun errore. Se un elemento viene modificato, non è un problema, altrimenti non potremmo neanche fare questo, ad esempio:
For Each U As User In Users
  If U.IsOnline Then
    U.Status = "Connesso"
  End If
Next

L'eccezione viene lanciata, ripeto, quando è la collezione ad essere modificata, ossia con operazioni di aggiunta, rimozione o inserimento. Inoltre, c'è un problema che non abbiamo considerato per questo metodo. Infatti, se i tuoi non sono stringhe ma oggetti, il Select di Linq si limita a selezionarli tutti e, poiché si tratta di valori di tipo reference, anche nella nuova collezione le variabili punteranno sempre agli stessi oggetti, con il risultato che se un elemento viene eliminato prima di essere letto, il suo riferimento non esisterà più. La logica soluzione sarebbe di usare la clonazione per effettuare una copia dell'oggetto in questione. Ma anche qui ci sono problemi: se l'oggetto non supporta l'interfaccia ICloneable, dovrai creare tu una funzione che esegue una copia intera dell'oggetto. Come se non bastasse, se l'oggetto ha come campi altri oggetti reference, bisogna considerare di clonare anche quelli, ossia bisogna effettuare una deep copy di tutto il grafo dell'oggetto. Questo risulterebbe in un carico eccessivo di memoria per il tuo processo, anche se si tratta di variabili temporanee.
aaa
01/06/09 8:42
Jeremy
Ciao Il Totem.
Il mio progettino di esempio, si riferiva al fatto di utilizzare l'interfaccia IEnumerable per il quale Goldberg ha fatto esplicito riferimento.
Il fatto che il mio codice non da errore non mi sembra una cosa da rimprovero :rofl: .
Lo scopo dell'esempio, non era produrre un errore, ma dimostrare una *possibile* e non assoluta soluzione.
Qualora gli elementi fossero riferimenti e non valori, bisognerebbe gestire l'eccezione NullReferenceException e considerare l'elemento *rimosso*, ma credo che, questa condizione, andrebbe gestita in ogni caso, a prescindere dalla tecnica che si utilizzi.
Non per fare polemica, ma che differenza c'è ad utilizzare il metodo Clone dell'interfaccia IClonable e utilizzare Linq a prescindere che l'oggetto sia IClonable o meno?
Ad ogni modo, anche se mi bacchetti sempre :noway: ... sei sempre un grande.
Ciao
Ultima modifica effettuata da Il Totem 02/06/09 9:16
aaa
01/06/09 13:36
GoLDBeRG
ho reso piu stabile l'invio dei messaggi usando come ha detto il buon caro vecchio totem il .Clone...

ho fatto un thread a parte con un ciclo infinito e uno sleep di 1 secondo che mi clona l'array di user in un array temporaneo che sarà soggetto al ciclo e mentre sul temporaneo ci sono i cicli l'originale viene modificato senza dare alcun errore.....
il problema sorge solo se l'array originale viene copiato esattamente durante uno dei cicli... ma credo ahime che questo non possa evitarlo... mi faro' bastare questa soluzione
aaa
02/06/09 9:16
Il Totem
Infatti, questo è un caso quanto meno singolare - criticare il fatto che non ci siano errori. Ma credevo volessi simulare la condizione in cui si trovava Goldberg, e quel codice non la rispecchiava, poiché si limita a modificare gli elementi della collezione, ma non la collezione stessa. Comunque pensavo che con IEnumerable, si riferisse all'enumerazione generalizzata di una collezione (con MoveNext e Current) e non al Linq, sebbene anche questo sia una soluzione possibile.
Per quanto riguarda il Close, ce n'è eccome di differenza: ho sperimentato sulla mia pelle quanto possa essere pericoloso sopravalutare Linq. Se tu con Linq selezioni gli oggetti di una collezione, ottieni sì una nuova collezione, ma formata sempre dagli stessi oggetti! Linq non clona i tipi reference, perciò anche avendo due variabili diverse, esse puntano alla stessa istanza, ed è questo che genera un errore. Invece, se nella query ci metti oggetti clonati, non ci sarà problema poiché i due saranno identici ma non uguali (nel senso che saranno due istanze diverse). Puoi vedere questo approccio nel programma GA Sequencer, nel metodo NextGeneration della classe GeneticEngine.
aaa
02/06/09 9:46
Jeremy
Ciao Totem

Ti devo dare, ancora una volta, ragione su tutto quanto mi hai contestato.
:hail::hail:
:hail:

cerca di capire ... ho bisogno di ferie.

Ciao
Ultima modifica effettuata da Jeremy 02/06/09 9:47
aaa
02/06/09 10:59
GoLDBeRG
va bene ragazzi basta che ho risolto piu o meno... non penso di poter fare meglio di cosi per ora
aaa