Home > Software engineering >  How to process data in passed to function in a channel?
How to process data in passed to function in a channel?

Time:01-14

I wrote a function that will split the array passed to it into other arrays, depending on the number 1 of the array. For example 3, 2, 1, 1, 8, 2, 2, 9, 9 will be turned into [2, 1, 1], [8], [9, 9].

static async Task Main(string[] args) {
    List<int> list = new List<int>() { 1, 2, 2, 5, 6, 3, 9, 9, 9 };

    var source1 = Try(list);

        foreach (var x in source1)
        {
            x.ForEach(i => Console.Write("{0} ", i));
            Console.WriteLine();
        }
}

static List<List<int>> Try(List<int> data, int d = 0)
    {

        var myChannel = Channel.CreateUnbounded<int>();

        List<List<int>> outList = new List<List<int>>();
        for (int p = 0; p < data.Count;)
        {
            d = data[p  ];    // Get the size of the array

            d = (d <= 0) ? 0 : d; // If the size is not correct, then we correct

            List<int> tempList = new List<int>(new int[d]); //creating a temp list
            for (var i = 0; i < d && p < data.Count; i  , p  )
                tempList[i] = data[p];   // Filling the array with data

            outList.Add(tempList);           // Result, Combining split arrays into one single sheet
        }
        return outList;
    }

I want to rewrite the code above to use Сhannel. That is, the input of the function receives a Сhannel with a sequence of numbers. The function processes them and returns the separated arrays in turn. But how can I do it using Channel?

And I wanted to try to read the size of the transmitted Сhannel, but it's not possible, as well as iterate over the elements of the transmitted Сhannel. I wanted to read them, then assign them to the List, process them and return the separated arrays one by one.

List<int> list = new List<int>() { 1, 2, 2, 5, 6, 3, 9, 9, 9 };

var myChannel = Channel.CreateUnbounded<int>() ;

_ = Task.Factory.StartNew(async () =>
        {
            foreach (var j in list)
            {
                await myChannel.Writer.WriteAsync(j);
                await Task.Delay(500); 
            }
        });

await foreach (var item in FetchItems2(myChannel))
        {
            Console.WriteLine($"{item}");
        }

static async IAsyncEnumerable<int[]> FetchItems2(Channel<int> data, int d = 0)
    {
        List<int> innerList = new List<int>();  

/*broken code taken from a past solution without using channels
        var item = await data.Reader.ReadAsync();

        for (int p = 0; p < data.Count;)
        {

            d = data[p  ];    // Get the size of the array

            d = (d <= 0) ? 0 : d; // If the size is not correct, then we correct
            int[] arr = new int[d]; // Create an array

            for (var i = 0; i < d && p < data.Count; i  , p  )
                arr[i] = data[p];   // Filling the array with data

            */
            yield return arr;           // returning split arrays
        }
    }

CodePudding user response:

Find a solution: 1 function was finalized and await was added to it when passing through all elements

static async Task Main(string[] args)
    {
        List<int> list = new List<int>() { 1, 2, 2, 5, 6, 3, 9, 9, 9 };

        var myChannel = Channel.CreateUnbounded<int>() ;

        _ = Task.Factory.StartNew(async () =>
        {
            foreach (var j in list)
            {
                await myChannel.Writer.WriteAsync(j);
                await Task.Delay(100); // just to see
            }
        }); // data in channel


        Console.WriteLine($"Start");
        await foreach (var item in FetchItems2(myChannel, list.Count))
        {
            //Console.WriteLine($"{item}");
            foreach(var x in item)
            {
                Console.Write($"{x} ");
            }
            Console.WriteLine();
        }
        Console.WriteLine($"End");

    }

static async IAsyncEnumerable<int[]> FetchItems2(Channel<int> data, int size, int d = 0)
    {
        List<int> innerList = new List<int>();

        for(int i = 0; i < size; i  )
        {
            innerList.Add(await data.Reader.ReadAsync());
        }

        for (int p = 0; p < innerList.Count;)
        {

            d = innerList[p  ];    // Get the size of the array

            d = (d <= 0) ? 0 : d; // If the size is not correct, then we correct
            int[] arr = new int[d]; // Create an array
                                    // create new list
            
            for (var i = 0; i < d && p < innerList.Count; i  , p  )
                arr[i] = innerList[p];   // Filling the array with data

            await Task.Delay(750);
            yield return arr;           // Result
        }
    }

The code is almost the same. In another way, data is written from the channel to the List. The array is read correctly, then outputs the data line by line via yield

  • Related