Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a program that posts multiple transactions to an API, on average about 40/50 transactions per day and the program runs once daily (as a job). I am getting an error 'Cannot write to a closed TextWriter' when the flow tries to loop through the second record. Only the first transaction is being posted but when the loop attempts second record the program either crashes or throws error 'Cannot write to a closed TextWriter'.


Program.cs
C#
<pre>List<Root2> details = GetRemmitances();
        var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.myloan.co.za/api/v1/inbound/create");
        ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Headers.Add("x-api-key", Helpers.apikey.ToString());
        httpWebRequest.Method = "POST";
        httpWebRequest.Timeout = 300000;

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {

            try
            {
                foreach (var tran in details)
                {
                    jsonRecord = JsonConvert.SerializeObject(tran);
                    
                }
                Console.WriteLine(jsonRecord);
                streamWriter.Write(jsonRecord);
                streamWriter.Flush();
                streamWriter.Close();
                var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

                    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                    {
                        result = streamReader.ReadToEnd();
                        if (!File.Exists(filePath))
                        {
                            File.Create(filePath).Dispose();
                        }
                        using (stream = File.AppendText(filePath))
                        {
                        stream.WriteLine(result);
                        stream.Flush();
                        stream.Close();
                        }
                    }
                   
              
            }
            catch (WebException ex)
            {
                ExceptionLogger.SendErrorToText(ex);
            }
          
        }  


What I have tried:

Having done some searching I have removed stream.Close(); and streamWriter.Close(); but this doesnt help either as the program continues to crash without throwing an error. I know that the using block also closes the TextWriter by definition so I have taken out all the logic out of the for loop as below :

C#
FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write);            
        StreamWriter sw = new StreamWriter(fs);
        StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream());
        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        StreamReader sr = new StreamReader(httpResponse.GetResponseStream());
        result = sr.ReadToEnd();
        foreach (var tran in details)
        {
            jsonRecord = JsonConvert.SerializeObject(tran);
            Console.WriteLine(jsonRecord);
            streamWriter.Write(jsonRecord);
            streamWriter.Flush();
            sw.WriteLine(result);
            sw.Flush();
        } 
       sw.Close();
       streamWriter.Close();  



This time I am getting error "400 Bad Request" despite that I am not posting a duplicate record (the upstream API doesnt accept duplicates and throws 400 Bad Request for such).

I am not sure if the refactor is entirely correct or how to change the original implementation if need be.

What am I missing?
Posted
Updated 12-Feb-22 4:53am
v2
Comments
Richard MacCutchan 12-Feb-22 8:00am    
I cannot see any calls to StreamWriter.Write after the Close call. But I note that your foreach loop will only process the vary last tran record in details.
foreach (var tran in details)
{
    jsonRecord = JsonConvert.SerializeObject(tran);
// maybe you should be writing the records inside this loop
}

1 solution

Try using the FileStream constructor with the FileShare parameter.
C#
FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); 
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900