Sets the global interval (for example, 0-1000). There is a write method that takes an interval from 0 to 200, as well as a string (denoted by S ). String S generated within a few minutes (generation goes to several threads), saves all strings to the list variable of the List<string>

I need to call the write method in several threads, sending it an interval after an interval (0-200, 200-400, etc.), as well as a new string S

I did this:

 globalto = 1000; globalfrom = 0; double k = (globalto - globalfrom) ; k /= 200; if (k > Math.Truncate(k)) k = Math.Truncate(k) + 1; long[] mas = new long[Convert.ToInt32(k)]; for (int i = 0; i < k; i++) mas[i] = globalfrom += 200; mas.AsParallel().WithDegreeOfParallelism(thread).ForAll(j => write(j - 200, j, "")); 

But here I am not sending the string S I don’t know how to implement correctly so that as soon as a string appears in the list variable, a thread is immediately created that will call the write method, sending the current row and a new segment, and so that all this continues until the end of the global interval is reached (0- 1000).

  • Is it by chance you have a producer / consumer? - VladD
  • @VladD did not quite understand you, but let there be an answer "no")) - Lolidze
  • @VladD can tell how to organize the whole thing? - Lolidze
  • @Lolidze, you need to keep track of the addition of an item to the collection and perform some actions, right? - Andrei NOP
  • @Andrey yes, as soon as a line was added to the collection, you need to create a stream that will call the method and send the current line and a new segment to it. It is IMPORTANT that new segments should be taken all the time, 0-200, 200-400, 400-600 and so on until the end of the global segment, in this case 1000 - Lolidze

2 answers 2

Variation Supplier / Consumer applicable to your task

 using System; using System.Collections.Concurrent; using System.Linq; using System.Threading; using System.Threading.Tasks; class Program { static void Main() => new Program().Run(); Random Rnd = new Random(); ConcurrentQueue<Interval> Items = new ConcurrentQueue<Interval>(); int bigSegment = 2000; int smallSegment = 200; bool HasFinished = false; void Run() { // ЗапускаСм ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ var consumers = Enumerable.Range(0, 5) .Select(i => Task.Run(() => Consumer(i))) .ToArray(); // ЗапускаСм поставщиков var producers = Enumerable.Range(0, bigSegment / smallSegment) .Select(i => Task.Run(() => Producer(i))) .ToArray(); // Π–Π΄Π΅ΠΌ всСх поставщиков Task.WaitAll(producers); // Π‘Ρ‚Π°Π²ΠΈΠΌ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ„Π»Π°Π³ HasFinished = true; // Π–Π΄Π΅ΠΌ всСх ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ Task.WaitAll(consumers); Console.WriteLine("Π Π°Π±ΠΎΡ‚Π° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°!"); Console.ReadLine(); } void Producer(int num) { Thread.Sleep(Rnd.Next(10) * 200); // Π˜ΠΌΠΈΡ‚Π°Ρ†ΠΈΡ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ // ДобавляСм сгСнСрированный элСмСнт Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ Items.Enqueue(new Interval { Num = num, S = $"Π‘Ρ‚Ρ€ΠΎΠΊΠ° {num}" }); Console.WriteLine($"ΠŸΠΎΡΡ‚Π°Π²Ρ‰ΠΈΠΊ {num} Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ» Ρ€Π°Π±ΠΎΡ‚Ρƒ"); } void Consumer(int num) { while (!HasFinished) { while (!Items.IsEmpty) { // ΠŸΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ элСмСнт ΠΈΠ· ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ if (Items.TryDequeue(out var item)) WriteAsync(item, num); } Thread.Sleep(100); // Π‘ΠΏΠΈΠΌ 0,1 с } Console.WriteLine($"ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ {num} Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ» Ρ€Π°Π±ΠΎΡ‚Ρƒ"); } void WriteAsync(Interval item, int num) { Thread.Sleep(Rnd.Next(10) * 100); // Π˜ΠΌΠΈΡ‚Π°Ρ†ΠΈΡ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Console.WriteLine($"ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ {num}: ΠΈΠ½Ρ‚Ρ€Π΅Π²Π°Π» {item.Num * smallSegment} - {(item.Num + 1) * smallSegment}, {item.S}"); } } struct Interval { public int Num { get; set; } public string S { get; set; } } 

I recommend to study additional answers in this question: Implementation of the Producer / Consumer pattern

  • IMHO, HasFinished must be marked volatile . - Alexander Petrov
  • @AlexanderPetrov like this volatile bool HasFinished = false; ? - Lolidze
 namespace ConsoleApplication1 { internal class Program { static List<string> list= new List<string>(); private static void Main(string[] args) { int globalto = 1000; int globalfrom = 0; int length = 200; for (int i=0; globalfrom +i*length<globalto;i++) { myFunc(globalfrom + i * length, Math.Min(globalfrom + (i+1) * length, globalto),i); } } private static async void myFunc(int from, int to,int number) { while (list.Count <= number) { await Task.Delay(TimeSpan.FromMilliseconds(50)); } write(from, to, list[string]); } } } 
  • I see something incomprehensible. async function is called without await . - Alexander Petrov
  • I mean the rules (not async) - write - Leonid Malyshev