C # StreamReader ReadLine () зависает со второй попытки, если потоки не выходят - PullRequest
0 голосов
/ 24 февраля 2019

Я унаследовал приведенный ниже код от другого разработчика, который отправляет запросы во внешнюю систему.

Я вызываю метод GenerateRequest, используя разные значения для параметра 'method' (из BackgroundWorker), все из которыхотлично работаетКогда я затем выполняю второй вызов, он все еще работает для всех, кроме одного из значений «метода» (которое также содержит различные значения для значения «параметров», я также включу вызовы ниже), которое висит на StreamReader ReadLine () вызов.Однако, если я отлаживаю и прошагаю по коду, разрешающему 10-20 секунд, вывод показывает несколько сообщений «Поток 0xd0f0 завершился с кодом 0 (0x0)», и код затем работает.

Я чувствую, что яУ меня есть проблема с темой, из которой я делаю эту работу, но я не могу понять это, пожалуйста, помогите.

Это работает каждый раз;

   ClientParameters parameters = new ClientParameters();
   string request = requestHandler.GenerateRequest("GetFunctions", parameters);

Это работает тольков первый раз, если я не отлаживаю и не выполняю шаги, чтобы у потоков было время на выход.

ClientParameters parameters = new ClientParameters();
        parameters.Filter = new ClientParametersFilter();
        parameters.Filter.Demographics = "";
        parameters.Filter.Medication = "";
        parameters.Filter.MinEffectiveDate = DateTime.Now;
        parameters.Filter.MaxEffectiveDate = DateTime.MaxValue;
        string request = null;
        try
        {
            request = requestHandler.GenerateRequest("GetRecord", parameters);
        }
        catch(Exception e)
        {
            // log error
            return null;
        }

Hear - класс для выполнения запросов;

public class MyRequestHandler : IRequestHandler{
public string GenerateRequest(string method, ClientParameters parameters)
{
    ClientIntegrationRequest request = new ClientIntegrationRequest();
    request.APIKey = ApplicationSettings.APIKey;
    request.Function = method;
    request.FunctionVersion = 1.0M;
    request.RequestUID = DateTime.Now.ToString();
    request.DeviceID = ApplicationSettings.DeviceId;
    request.DeviceVersion = ApplicationSettings.DeviceVersion;
    request.FunctionParameters = parameters;

    XmlSerializer ser = new XmlSerializer(typeof(ClientIntegrationRequest));
    string xml;
    using (MemoryStream m = new MemoryStream())
    {
        ser.Serialize(m, request);
        // reset to 0
        m.Position = 0;
        xml = new StreamReader(m).ReadToEnd();
    }

    try
    {
        TcpClient tcpClient = new TcpClient("127.0.0.1", ApplicationSettings.Port);
        NetworkStream netStream = tcpClient.GetStream();
        if (netStream.CanWrite)
        {
            xml = xml + "\n";
            Byte[] sendBytes = Encoding.UTF8.GetBytes(xml);
            netStream.Write(sendBytes, 0, sendBytes.Length);
            netStream.Flush();
        }
        else
        {
            tcpClient.Close();
            netStream.Close();
            return null;
        }
        netStream = tcpClient.GetStream();
        if (netStream.CanRead)
        {
            StreamReader l_textReader = new StreamReader(netStream);
            string str = l_textReader.ReadLine(); // Here's the issue
            l_textReader.Close();           
            tcpClient.Close();
            netStream.Close();
            return str.ToString();
        }
        else
        {
            tcpClient.Close();
            netStream.Close();
            return null;
        }
    }
    catch (SocketException e)
    {
        // log error
        return null;
    }
    catch (Exception e)
    {
        // log error
        return null;
    }
}}

1 Ответ

0 голосов
/ 24 февраля 2019

Если вы посмотрите пример Microsoft: https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.getstream?view=netframework-4.7.2, вы можете увидеть, что код читает поток клиента по низкоуровневому коду, читая содержимое, возвращаемое байтовым массивом:

if (netStream.CanRead)
{
    // Reads NetworkStream into a byte buffer.
    byte[] bytes = new byte[tcpClient.ReceiveBufferSize];

    // Read can return anything from 0 to numBytesToRead. 
    // This method blocks until at least one byte is read.
    netStream.Read (bytes, 0, (int)tcpClient.ReceiveBufferSize);

    // Returns the data received from the host to the console.
    string returndata = Encoding.UTF8.GetString (bytes);

    Console.WriteLine ("This is what the host returned to you: " + returndata);

}

Можете ли выпопробовать этот метод чтения?

...