-2

I feel super confused... I am trying to implement an asynchronous C# call to a Web API to translate a list of values, the result I expect is another list in a 1 to 1 fashion. We don't mind about order, we are just interested in speed and to our knowledge the servers are capable to process the load.

private object ReadFileToEnd(string filePath)
{
    //file read logic and validations...
    string[] rowData = new string[4]; //array with initial value
    rowData = translateData(rowData);
}

private async Task<List<string>> translateData(string[] Collection)
{
     //The resulting string collection.
     List<string> resultCollection = new List<string>();

     Dictionary dict = new Dictionary();

     foreach (string value in Collection)
     {
         Person person = await Task.Run(() => dict.getNewValue(param1, param2, value.Substring(0, 10)));

         value.Remove(0, 10);

         resultCollection.Add(person.Property1 + value);
     }

     return resultCollection;
}

I might have other problems, like the return type, I am just not getting it to work. My main focus is the multithread and returning an string array. The main thread is coming from ReadFileToEnd(...) already noticed that if I add the await it will require to add async to the function, I am trying not to change too much.

Edgar J. Rodriguez
  • 285
  • 1
  • 2
  • 13
  • `translateData` returns `Task>` but you want to assign it to `string[] rowData` – L.B Aug 24 '17 at 20:15
  • `value.Remove(0, 10);` you don't assign the returned value to any variable – L.B Aug 24 '17 at 20:17
  • `await Task.Run(action)` is not faster than `action()`. – L.B Aug 24 '17 at 20:23
  • `string[] rowData = new string[4]; //array with initial value` You don't have to initialize it if you want to assign a new value to it. `string[] rowData = translateData(rowData);` is enough. Even simpler `var rowData = translateData(rowData);` – L.B Aug 24 '17 at 20:26
  • `private object ReadFileToEnd` you don't return anything in *ReadFileToEnd* – L.B Aug 24 '17 at 20:28
  • **I am just not getting it to work.** Not a surprise – L.B Aug 24 '17 at 20:29
  • 2
    to think that adding async/await decoration to a data processing loop would make it faster, or more efficient, or whatever is just not true. there are two good reasons to use the async/await pattern and that is 1) to ensure a user interface will stay responsive under load and 2) to apply it to algorithms which actually profit from parallel execution, and which are designed with parallelity in mind. In your case, at least far as I can tell from the code you posted, parallelity will just induce an unnecessary overhead. – Cee McSharpface Aug 24 '17 at 20:42
  • By the way, I made a parallel version of whatever you were trying to do before. But you may need to elaborate a little bit more before asking :-( – Miguel Aug 24 '17 at 20:45

1 Answers1

0

Use a Parallel ForEach to iterate and remove the await call inside each loop iteration.

        private IEnumerable<string> translateData(string[] Collection)
        {
            //The resulting string collection.
            var resultCollection = new ConcurrentBag<string>();

            Dictionary dict = new Dictionary();

            Parallel.ForEach(Collection,
                value =>
                {
                    var person = dict.getNewValue(param1, param2, value.Substring(0, 10));
                    value.Remove(0, 10);
                    resultCollection.Add(person.Property1 + value);
                });

            return resultCollection;
        }

Your attempt and parallelism is not correct. You are doing nothing if everytime you send a Parallel request to the translate you stop your current iteration and wait for a result (without continuing the loop).

Hope this help!

Miguel
  • 3,786
  • 2
  • 19
  • 32