Comment utiliser correctement .NET2.0 port série .BaseStream pour l'opération asynchrone

Je suis tenter de l'utiliser .BaseStream propriété de l' .NET2.0 SerialPort faire asynchrone lit et écrit (méthodes beginwrite/EndWrite, BeginRead/EndRead).

Je vais avoir quelques succès dans ce, mais après un certain temps, j'ai remarqué (à l'aide de l'Explorateur de Processus) une augmentation progressive dans les Poignées de l'application est à l'aide de, et, occasionnellement, un fil supplémentaire, ce qui augmente aussi le nombre de handles.

Le changement de contexte de taux augmente également chaque fois qu'un nouveau fil apparaît.

L'application envoie sans cesse de 3 octets à un AUTOMATE appareil, et obtient de 800 octets en retour, et à un taux de transmission de 57600.

La première CSwitch Delta (encore une fois, à partir de l'Explorateur de Processus) est de l'ordre de 2 500, ce qui semble très élevé, de toute façon. Chaque fois qu'un nouveau fil apparaît, l'augmentation de cette valeur, et la charge CPU augmente en conséquence.

Je suis en espérant que quelqu'un pourrait faire quelque chose de similaire, et peut m'aider, ou même de dire " Au nom de Dieu, de ne pas le faire de cette façon.'

Dans le code ci-dessous, " cela._stream " est obtenue à partir SerialPort.BaseStream, et CommsResponse est une classe que j'utilise comme IAsyncresult d'état de l'objet.

Ce code est commun à une connexion TCP que je fais comme une alternative à l'utilisation du port série, (j'ai un CommsChannel de la classe de base, avec un numéro de série et TCP canal dérivé) et qu'il n'en a aucun de ces problèmes, donc je suis raisonnablement optimiste qu'il n'y a rien de mal avec le CommsResponse classe.

Toutes les observations reçues avec reconnaissance.

    ///<summary>
///Write byte data to the channel.
///</summary>
///<param name="bytes">The byte array to write.</param>
private void Write(byte[] bytes)
{
try
{
//Write the data to the port asynchronously.
this._stream.BeginWrite(bytes, 0, bytes.Length, new AsyncCallback(this.WriteCallback), null);
}
catch (IOException ex)
{
//Do stuff.
}
catch (ObjectDisposedException ex)
{
//Do stuff.
}
}
///<summary>
///Asynchronous write callback operation.
///</summary>
private void WriteCallback(IAsyncResult ar)
{
bool writeSuccess = false;
try
{
this._stream.EndWrite(ar);
writeSuccess = true;
}
catch (IOException ex)
{
//Do stuff.
}
//If the write operation completed sucessfully, start the read process.
if (writeSuccess) { this.Read(); }
}
///<summary>
///Read byte data from the channel.
///</summary>
private void Read()
{
try
{
//Create new comms response state object.
CommsResponse response = new CommsResponse();
//Begin the asynchronous read process to get response.
this._stream.BeginRead(this._readBuffer, 0, this._readBuffer.Length, new AsyncCallback(this.ReadCallback), response);
}
catch (IOException ex)
{
//Do stuff.
}
catch (ObjectDisposedException ex)
{
//Do stuff.
}
}
///<summary>
///Asynchronous read callback operation.
///</summary>
private void ReadCallback(IAsyncResult ar)
{
//Retrieve the comms response object.
CommsResponse response = (CommsResponse)ar.AsyncState;
try
{
//Call EndRead to complete call made by BeginRead.
//At this point, new data will be in this._readbuffer.
int numBytesRead = this._stream.EndRead(ar);
if (numBytesRead > 0)
{
//Create byte array to hold newly received bytes.
byte[] rcvdBytes = new byte[numBytesRead];
//Copy received bytes from read buffer to temp byte array
Buffer.BlockCopy(this._readBuffer, 0, rcvdBytes, 0, numBytesRead);
//Append received bytes to the response data byte list.
response.AppendBytes(rcvdBytes);
//Check received bytes for a correct response.
CheckResult result = response.CheckBytes();
switch (result)
{
case CheckResult.Incomplete: //Correct response not yet received.
if (!this._cancelComm)
{
this._stream.BeginRead(this._readBuffer, 0, this._readBuffer.Length,
new AsyncCallback(this.ReadCallback), response);
}
break;
case CheckResult.Correct:  //Raise event if complete response received.
this.OnCommResponseEvent(response);
break;
case CheckResult.Invalid: //Incorrect response
//Do stuff.
break;
default: //Unknown response
//Do stuff.
break;
}
}
else
{
//Do stuff.
}
}
catch (IOException ex)
{
//Do stuff.
}
catch (ObjectDisposedException ex)
{
//Do stuff.
}
}

OriginalL'auteur Andy | 2009-01-20