Comment Asynchrone De Lecture/Écriture D'Un Tube Nommé En C#

J'ai un formulaire Windows qui héberge une coutume de Contrôle de l'Utilisateur. Ce Contrôle Utilisateur déclenche un processus séparé (un .exe) qui crée et initialise une NamedPipeServerStream. Une fois le processus initialise le NamedPipeServerStream, le Contrôle de l'Utilisateur se connecte à elle comme un NamedPipeClientStream.

Tout cela fonctionne très bien.

Sur l'écran de Windows j'ai ensuite un bouton "Check For Updates". Lorsque ce bouton est pressé, la NamedPipeClientStream envoie un message au serveur, dans lequel le serveur qui répond à une MessageBox en disant: "j'ai été dit de vérifier les mises à jour". Donc je peux dire ce client > serveur de communication fonctionne bien.

Voici le problème. Le serveur est alors censé envoyer un message vers le client en lui disant que c'est maintenant la vérification de mises à jour (pour le Contrôle de l'Utilisateur peut mettre à jour son statut après verying sa commande a été reçue par le serveur). Mais chaque fois que cela arrive, tout se bloque.

Maintenant, je vais supposer que c'est parce que j'essaie à la fois de lire ET d'écrire sur le canal Nommé en même temps?

Ci-dessous quelques extraits de code à partir à la fois le Serveur et le Client. (Ces deux extraits de courir sous la forme de plusieurs threads dans leurs processus respectifs de manière à ne pas bloquer l'INTERFACE utilisateur)

GUpdater (Le Serveur De Canal Nommé):

private void WaitForClientCommands()
{
    //Wait for a connection from a Named Pipe Client (The GUpControl)
    pipeStream.WaitForConnection();
    pipeConnected = true;

    //Create a StreamWriter/StreamReader so we can write/read to the Named Pipe
    pipeStreamWriter = new StreamWriter(pipeStream) { AutoFlush = true };
    pipeStreamReader = new StreamReader(pipeStream);

    //Now that we have a connection, start reading in messages and processing them
    while (true)
    {
        //Skip this time if we are currently writing to the pipe
        if(isWritingToPipe) continue;

        var message = pipeStreamReader.ReadLine();
        if (message == null)
        {
            //We don't want to hog up all the CPU time, so if no message was reaceived this time, wait for half a second
            Thread.Sleep(500);
            continue;
        }

        switch(message)
        {
            case "CheckForUpdates":
                //MessageBox.Show("Told to check for updates");
                SendMessageToClient("Checking For Updates, Woot!");
                break;
            case "DownloadUpdate":
                MessageBox.Show("Told to download update");
                break;
            case "ApplyUpdate":
                MessageBox.Show("Told to apply update");
                break;
        }
    }
}

GUpControl (Le Client De Canal Nommé):

private void WaitForServerCommands()
{
    if(!pipeConnected) return;

    //Now that we have a connection, start reading in messages and processing them
    while (true)
    {
        //Skip this time if we are currently writing to the pipe
        if (isWritingToPipe) continue;

        //Attempt to read a line from the pipe
        var message = pipeStreamReader.ReadLine();
        if (message == null)
        {
            //We don't want to hog up all the CPU time, so if no message was reaceived this time, wait for half a second
            Thread.Sleep(500);
            continue;
        }

        MessageBox.Show("I got a message from the server!!\r\n" + message);
    }
}

L'extrait de code suivant est la méthode qui est responsable de la rédaction pour le Client/Serveur de chaque composant. (La seule différence est dans le nom, c'est à dire SendMessageToClient et SendMessageToServer)

private void SendMessageToServer(string message)
{
    if(pipeConnected)
    {
        isWritingToPipe = true;
        pipeStreamWriter.WriteLine(message);
        isWritingToPipe = false;
    }
}

La isWritingToPipe variable est un simple booléen qui est vrai lorsque le processus tente d'écrire le canal Nommé. C'était ma première tentative de résoudre le problème.

Toute aide est très appréciée!

  • tout plein des exemples de code source?
InformationsquelleAutor Tom Glenn | 2010-12-20