Многопоточное приложение. При выполнении получатся большие разбросы в показаниях секундомера - C#

Узнай цену своей работы

Формулировка задачи:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Management.Instrumentation;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Timers;

namespace Test
{
    class Program
    {
        
        static bool TF1 = true;
        static bool TF2 = true;
        static bool TF3 = true;
        static bool TF4 = true;
        
        static Int64 S1 = 100000000;
        static Int64 S2 = 100000000;
        static Int64 S3 = 100000000;
        static Int64 S4 = 100000000;

        static void Main(string[] args)
        {
                    Thread Stream1 = new Thread(ST1);
                    Stream1.Start();
                    Thread Stream2 = new Thread(ST2);
                    Stream2.Start();
                    
                    Thread Stream3 = new Thread(ST3);
                    Stream3.Start();
                    Thread Stream4 = new Thread(ST4);
                    Stream4.Start(); 
            
        }
        static void ST1()
        {
            Stopwatch DO1 = new Stopwatch();
            Console.WriteLine("Поток 1 ...запущен");
            while (TF1)
            {
                switch (S1)
                {
                    case 100000000:
                        DO1.Start();
                        break;
                    case 0:
                        DO1.Stop();
                        TF1 = false;
                        break;
                }
                Math.Tan(S1);
                S1--;
            }
            Console.WriteLine("Поток 1 завершен: " + DO1.Elapsed);
            Console.ReadKey();
        }
        static void ST2()
        {
            Stopwatch DO2 = new Stopwatch();
            Console.WriteLine("Поток 2 ...запущен");
            while (TF2)
            {
                switch (S2)
                {
                    case 100000000:
                        DO2.Start();
                        break;
                    case 0:
                        DO2.Stop();
                        TF2 = false;
                        break;
                }
                Math.Tan(S2);
                S2--;
            }
            Console.WriteLine("Поток 2 завершен: " + DO2.Elapsed);
            Console.ReadKey();
        }
        
        static void ST3()
        {
            Stopwatch DO3 = new Stopwatch();
            Console.WriteLine("Поток 3 ...запущен");
            while (TF3)
            {
                switch (S3)
                {
                    case 100000000:
                        DO3.Start();
                        break;
                    case 0:
                        DO3.Stop();
                        TF3 = false;
                        break;
                }
                Math.Tan(S3);
                S3--;
            }
            Console.WriteLine("Поток 3 завершен: " + DO3.Elapsed);
            Console.ReadKey();
        }
        static void ST4()
        {
            Stopwatch DO4 = new Stopwatch();
            Console.WriteLine("Поток 4 ...запущен");
            while (TF4)
            {
                switch (S4)
                {
                    case 100000000:
                        DO4.Start();
                        break;
                    case 0:
                        DO4.Stop();
                        TF4 = false;
                        break;
                }
                Math.Tan(S4);
                S4--;
            }
            Console.WriteLine("Поток 4 завершен: " + DO4.Elapsed);
            Console.ReadKey();
        }
        
    }
}
При выполнении получатся большие разбросы в показаниях секундомера, в то время как 2 потока обрабатываются корректно.

Решение задачи: «Многопоточное приложение. При выполнении получатся большие разбросы в показаниях секундомера»

textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    public class TesterEventArgs : EventArgs
    {
        public TesterEventArgs(TimeSpan timeSpan)
        {
            TimeSpan = timeSpan;
        }
 
        public TimeSpan TimeSpan { get; set; }
    }
 
    public class Tester
    {
        private bool _tF1 = true;
        private const int MaxIteration = 100000000;
        private Int64 _s1 = MaxIteration;
        private Thread _thread;
        private readonly SynchronizationContext _syncContext;
 
        public Tester(SynchronizationContext syncContext)
        {
            _syncContext = syncContext;
        }
 
        public Tester()
            : this(null)
        {
        }
 
        public string Name { get; set; }
 
        public event EventHandler WorkStarted;
        public event EventHandler<TesterEventArgs> WorkEnded;
 
        protected virtual void OnWorkEnded(TesterEventArgs e)
        {
            SendOrPostCallback callback = obj =>
                {
                    EventHandler<TesterEventArgs> handler = WorkEnded;
                    if (handler != null) handler(this, e);
                };
 
            if (_syncContext != null)
                _syncContext.Post(callback, null);
            else
                callback(null);
        }
 
        protected virtual void OnWorkStarted()
        {
            SendOrPostCallback callback = obj =>
                {
                    EventHandler handler = WorkStarted;
                    if (handler != null) handler(this, EventArgs.Empty);
                };
            if (_syncContext != null)
                _syncContext.Post(callback, null);
            else
                callback(null);
        }
 
        public void Run()
        {
            _thread = new Thread(DoWork);
            _thread.Start();
        }
 
        protected void DoWork()
        {
            Stopwatch stopwatch = new Stopwatch();
            OnWorkStarted();
 
            while (_tF1)
            {
                if (_s1 == MaxIteration)
                {
                    stopwatch.Start();
                }
                else if (_s1 == 0)
                {
                    stopwatch.Stop();
                    _tF1 = false;
                }
                Math.Tan(_s1--);
            }
            OnWorkEnded(new TesterEventArgs(stopwatch.Elapsed));
        }
    }
 
    class Program
    {
 
        private static void Main(string[] args)
        {
            var testers = new[]
            {
 //Для Windows Forms или WPF позволит выполнить обработчик в UI потоке
                new Tester(SynchronizationContext.Current), 
                new Tester(SynchronizationContext.Current), 
                new Tester(SynchronizationContext.Current), 
                new Tester(SynchronizationContext.Current), 
             };
 
            for (int i = 0; i < testers.Length; i++)
            {
                testers[i].Name = i.ToString();
                testers[i].WorkStarted += Tester_WorkStarted;
                testers[i].WorkEnded += Tester_WorkEnded;
                testers[i].Run();
            }
 
            Console.ReadKey();
        }
 
        static void Tester_WorkStarted(object sender, EventArgs e)
        {
            var tester = (Tester)sender;
            tester.WorkStarted -= Tester_WorkStarted;
            Console.WriteLine("Поток {0} запущен", tester.Name);
        }
 
        static void Tester_WorkEnded(object sender, TesterEventArgs e)
        {
            var tester = (Tester)sender;
            tester.WorkEnded -= Tester_WorkEnded;
            Console.WriteLine("Поток {0} завершен: {1}", tester.Name, e.TimeSpan);
        }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4 из 5
Похожие ответы