aksl14 Ответов: 0

Загрузка массива байтов в поток памяти на asynccallback, но является нулевой, когда он возвращается в основной поток


У меня есть пример приложения, которое отправляет TCP-запрос на сервер, и сервер возвращает массив байтов. Затем он сохраняется в потоке памяти для обработки. Клиент, по-видимому, успешно сохраняет массив байтов в потоке памяти, так как при установке точки останова в коде перед тем, как он покинет функцию, поток памяти содержит в себе данные.

enum type
{
    Audio,
    Update
}

class NetworkObject
{
    public TcpClient tcp;
    public type ConnectionType;
    public string URL;
    public MemoryStream AudioMemoryStream;
}

private TcpClient tcpclientAudio = new TcpClient();
private NetworkObject audioObj = null;


private void button1_Click(object sender, EventArgs e)
{
    if (tcpclientAudio.Connected)
        tcpclientAudio.Close();
    tcpclientAudio = new TcpClient();

    // id is the call id of the audio you want to get

    // Image Test
    string audioId = recordIdTextBox.Text.Trim();
    string audioType = type.Audio.ToString();

    string message = "GET /fred?id=" + audioId + "&live=false HTTP/1.1\r\n" + "Sec-WebSocket-Key: 4eW1rRpCzr60VdvY3lZZMw==\r\n";

    audioObj = new NetworkObject();
    audioObj.tcp = tcpclientAudio;
    audioObj.ConnectionType = type.Audio;
    audioObj.URL = message;
    audioObj.AudioMemoryStream = new MemoryStream();

    tcpclientAudio.BeginConnect(IPAddress.Parse("127.0.0.1"), 8008, new AsyncCallback(CallBackConnectMethod), audioObj);
}

void CallBackConnectMethod(IAsyncResult result)
{
    NetworkObject obj = (NetworkObject)result.AsyncState;

    TcpClient tcp = obj.tcp;

    NetworkStream ns = tcp.GetStream();

    byte[] buffer = new byte[2048];
    int read = 0;
    string message = obj.URL;
    byte[] request = Encoding.ASCII.GetBytes(message);
    ns.Write(request, 0, request.Length);
    read = ns.Read(buffer, 0, 1000);

    Console.WriteLine(Encoding.ASCII.GetString(buffer, 00, read));

    obj.AudioMemoryStream = new MemoryStream();
    // check for switching protocols
    do
    {
        try
        {
            read = ns.Read(buffer, 0, 1);
            if (buffer[0] == 0x82)
            {
                read = ns.Read(buffer, 0, 1);
                int len = 0;
                switch (buffer[0])
                {
                    case 126:
                        read = ns.Read(buffer, 0, 2);
                        len = (buffer[0] << 8) + buffer[1];
                        break;
                    default:
                        len = buffer[0];
                        break;
                 }

                 read = ns.Read(buffer, 0, len);
                 if (obj.ConnectionType == type.Update)
                     Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, read));
                 else
                 {
                     obj.AudioMemoryStream.Write(buffer, 0, read);
                 }
             }
             else
             {
                 ns.Close();
                 read = 0;
             }
         }
         catch (Exception)
         {
             read = 0; // connection is lost
         }
     }
     while (read > 0);

     Debug.WriteLine("Just leaving");
}


Что я уже пробовал:

Первоначально поток памяти не был в классе NetworkObject, но он был добавлен, поскольку он определен вне потока и передан внутрь. Поскольку он инициализирован и заполнен потоком, я надеялся, что он все еще будет доступен в основном потоке, как только он будет заполнен.

Gerry Schmitz

На "главном потоке" для чего? Это просто выглядит так, как будто вы делаете кучу "локальных" вещей.

Richard Deeming

Вы не показали код, где вы проверяете поток. По-видимому, вы пытаетесь получить к нему доступ до того, как обратный вызов завершит выполнение.

aksl14

Я запускаю это как приложение forms в dev studio. Я нажимаю кнопку, и она запускает запрос tcp. Затем я использую точку останова на отладке "просто уходя".writeline для проверки того, что находится в потоке памяти. Как только это произошло, я "продолжаю" в отладчике и нажимаю другую кнопку, которая имеет точку останова. Пройдя через него, я обнаружил свою ошибку, так как если бы поток не был нулевым, я закрывал его. Удаление проверки теперь означает, что она работает.

0 Ответов