Hello
Hello

Reputation: 84

Exception while appending the deserialized output of json in a file

Scenario:

I am calling a Web API from a console application which has image(s) as input. The output is in JSON format which I have de-serialized.

static void Main()
{
    DirectoryInfo di = new DirectoryInfo(@"C:\Test\Images");
    var extensions = new[] { "*.png", "*.jpg", "*.jpeg" };     
    var files = extensions.SelectMany(ext => di.GetFiles(ext));

        foreach (FileInfo file in files)
        {
            string imageFilePath = file.FullName;
             // Execute the REST API call.
            MakeAnalysisRequest(imageFilePath);
        }        
}

static async void MakeAnalysisRequest(string imageFilePath)
{
    //logic - request response Web API
    //.....
    string contentString = await response.Content.ReadAsStringAsync();
    Console.WriteLine(JsonPrint(contentString,imageFilePath);
}

static string JsonPrint(string contentString,string imageFilePath)
{
    //sb is the json string
     dynamic obj = JsonConvert.DeserializeObject(sb.ToString());
     var anger = obj[0].faceAttributes.emotion.anger;
     var happy = obj[0].faceAttributes.emotion.happy;

        StringBuilder str = new StringBuilder();
        str.Append("Anger = " +anger);
        str.Append("Happy = "+happy);

        string path = @"C:\Users\Desktop\Face.txt";
        TextWriter tw = new StreamWriter(path, true);
        tw.WriteLine(str.ToString());
        tw.Close();

return str.ToString();
}

Issue: If the input is a single image, then there is no exception. But for multiple files, I get the following exception:

System.IO.IOException: 'The process cannot access the file 'C:\Users\Desktop\Face.txt' because it is being used by another process.'

Note:

If there are 10 images as an input, and if the exception occurs after 2 or 3 images are called, then the data of these few files are stored in the file.

Upvotes: 0

Views: 62

Answers (1)

Ray Krungkaew
Ray Krungkaew

Reputation: 6965

The error is thrown as expected since you access the same file by at the same time by multiple threads.

1. Change main to async and await for analysis result.

await MakeAnalysisRequest(imageFilePath);

And change the MakeAnalysisRequest method to be

static async Task MakeAnalysisRequest(string imageFilePath)

And the Main method to be

static async Task Main()

2. or Wait for the result without changing Main

MakeAnalysisRequest(imageFilePath).Wait();

3. You can also make the method can be accessed in sequence only

private static object sync = new object();
static string JsonPrint(string contentString, string imageFilePath)
{
    lock (sync)
    {
        //DO STUFF
    }
}

Upvotes: 1

Related Questions