Domanda

Sto avendo un comportamento strano in una domanda che mi è sconcertante.

creo un filo, chiamiamola dei lavoratori, che è responsabile per la gestione delle richieste di comunicazione. I clienti scrivono su un tubo mentre il thread consuma le richieste e inviare messaggi.

Ora, il ciclo principale del thread ha qualcosa di simile:

lock(this)
{
  object_id = Transport.BeginSend(xxx, xxx, callback, yyy)
  clientsObjects[object_id] = client_id;
}

Ora la richiamata deve accedere al client_id (è un po 'più complicato di quello che ho scritto, ma la cosa è che il callback riceve l'object_id, basta assumere BeginSend è una chiamata a UdpClient.BeginSend

void Callback(IAsyncResult ar)
{
  State st = (State)ar;
  lock(this)
  {
    client_id = clientsObjects[st.object_id]
  }
}

Serrature ci sono perché la richiamata può sparare così velocemente che in realtà accade prima clientsObjects[object_id] = client_id; possa eseguire ...

Ok, ora .. il problema è che è non funziona, funziona bene ora e poi ... perché? Se io traccio le ManagedThreadIds dei fili che stanno eseguendo il BeginSend e quello che sta eseguendo il callback trovo che a volte, hanno lo stesso ThreadId !!

È possibile? Come può succedere? Qualche suggerimento su quello che sto facendo di sbagliato?

Commento: codice vero e proprio non è esattamente così, trasporto è un wrapper per la classe UdpClient, che permette di cambiare il livello di trasporto facilmente, serrature non sono realmente le serrature ma spinlocks ... ma il concetto in sé è più o meno quello che ho' hai scritto verso il basso.

È stato utile?

Soluzione

Qui è un articolo vecchio che parla sulla funzione Stream.BeginRead () che opera in modo sincrono, asincrono, non come ci si aspetterebbe. L'articolo è a partire dal 2004, in modo da sto supponendo che riferisce a .NET 1.0 / 1.1. L'articolo non si riferisce specificatamente alle UdpClient.BeginSend (), ma mi sono spesso chiesto se le funzioni BeginXXX della roba Socket hanno lo stesso comportamento a volte, soprattutto se ci sono dati da leggere immediatamente. Potrebbe essere la pena di verificare il web per vedere se questa è una possibilità.

E 'possibile passare il client_id alla funzione di callback tramite il parametro stato della funzione BeginSend ()?

   object_id = Transport.BeginSend(xxx, xxx, Callback, client_id);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top