C#StreamReader ReadLine()在第二次尝试时挂起,除非线程退出

时间:2019-02-23 22:39:29

标签: c# backgroundworker tcpclient streamreader

我已经从另一个开发人员那里继承了下面的代码,该代码向外部系统发出请求。

我使用“方法”参数的不同值(来自BackgroundWorker)来调用GenerateRequest方法,所有这些方法都能正常工作。当我再进行第二次调用时,它仍然适用于除“ method”值之一(其中也包含“ parameters”值的不同值,我也将在下面包括这些调用)之外的所有值,该值挂在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;
        }

听是发出请求的类;

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 :(得分:1)

如果您查看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);

}

您可以尝试这种阅读方法吗?