Многопоточное приложение. При выполнении получатся большие разбросы в показаниях секундомера - 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();
}
}
}Решение задачи: «Многопоточное приложение. При выполнении получатся большие разбросы в показаниях секундомера»
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);
}
}
}