mirror of
https://github.com/farcasclaudiu/SmartThreadPool.git
synced 2026-06-22 15:01:24 +03:00
244 lines
7.5 KiB
C#
244 lines
7.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Threading;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Animation;
|
|
using System.Windows.Shapes;
|
|
using System.Windows.Threading;
|
|
using Amib.Threading;
|
|
using Microsoft.Phone.Controls;
|
|
|
|
namespace STPWPDemo
|
|
{
|
|
public partial class MainPage : PhoneApplicationPage
|
|
{
|
|
private const int MaxThreads = 10;
|
|
|
|
private readonly DispatcherTimer _timer;
|
|
|
|
private bool _running = false;
|
|
private SmartThreadPool _stp;
|
|
private readonly Thread _producer;
|
|
private int _workItemPerSec;
|
|
private int _workItemDuration;
|
|
private readonly AutoResetEvent _wakeupEvent = new AutoResetEvent(false);
|
|
|
|
// Constructork
|
|
public MainPage()
|
|
{
|
|
InitializeComponent();
|
|
|
|
_timer = new DispatcherTimer();
|
|
_timer.Interval = new TimeSpan(0, 0, 0, 0, 500);
|
|
_timer.Tick += _timer_Tick;
|
|
_timer.Start();
|
|
|
|
_producer = new Thread(WorkItemsProducer);
|
|
_producer.IsBackground = true;
|
|
_workItemDuration = Convert.ToInt32(txtWorkItemDuration.Text);
|
|
_workItemPerSec = Convert.ToInt32(txtWorkItemPerSec.Text);
|
|
|
|
usageControl1.Visibility = Visibility.Visible;
|
|
usageControl1.Maximum = MaxThreads;
|
|
usageHistoryControl1.Maximum = MaxThreads;
|
|
|
|
usageControl1.Maximum = Convert.ToInt32(txtMaxThreads.Text);
|
|
usageControl1.Value1 = 0;
|
|
usageControl1.Value2 = 0;
|
|
|
|
_producer.Start();
|
|
}
|
|
|
|
void _timer_Tick(object sender, EventArgs e)
|
|
{
|
|
SmartThreadPool stp = _stp;
|
|
if (null == stp)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int threadsInUse = (int)_stp.PerformanceCountersReader.InUseThreads;
|
|
int threadsInPool = (int)_stp.PerformanceCountersReader.ActiveThreads;
|
|
|
|
txtUsedThreads.Text = threadsInUse.ToString();
|
|
txtThreadsInPool.Text = threadsInPool.ToString();
|
|
usageControl1.Value1 = threadsInUse;
|
|
usageControl1.Value2 = threadsInPool;
|
|
usageHistoryControl1.AddValues(threadsInUse, threadsInPool);
|
|
}
|
|
|
|
private void btnStart_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (_running)
|
|
{
|
|
_wakeupEvent.Set();
|
|
_stp.Cancel();
|
|
_stp.Shutdown(false, 5000);
|
|
_stp = null;
|
|
btnStart.Content = "Start";
|
|
//txtIdleTimeout.Enabled = true;
|
|
_running = false;
|
|
}
|
|
else
|
|
{
|
|
usageHistoryControl1.Reset();
|
|
usageControl1.Value1 = 0;
|
|
usageControl1.Value2 = 0;
|
|
_wakeupEvent.Set();
|
|
_running = true;
|
|
btnStart.Content = "Stop";
|
|
//txtIdleTimeout.Enabled = false;
|
|
STPStartInfo stpStartInfo = new STPStartInfo()
|
|
{
|
|
MinWorkerThreads = Convert.ToInt32(txtMinThreads.Text),
|
|
MaxWorkerThreads = Convert.ToInt32(txtMaxThreads.Text),
|
|
IdleTimeout = Convert.ToInt32(txtIdleTimeout.Text) * 1000,
|
|
EnableLocalPerformanceCounters = true,
|
|
};
|
|
|
|
_stp = new SmartThreadPool(stpStartInfo);
|
|
}
|
|
}
|
|
|
|
private void WorkItemsProducer()
|
|
{
|
|
int timeout = _workItemPerSec == 0 ? Timeout.Infinite : (1000 / _workItemPerSec);
|
|
while (true)
|
|
{
|
|
bool signal = _wakeupEvent.WaitOne(timeout);
|
|
if (!signal)
|
|
{
|
|
SmartThreadPool stp = _stp;
|
|
if (stp != null)
|
|
{
|
|
try
|
|
{
|
|
stp.QueueWorkItem(Sleep);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// UI changed _workItemPerSec
|
|
int workItemPerSec = _workItemPerSec;
|
|
timeout = workItemPerSec == 0 ? Timeout.Infinite : (1000 / workItemPerSec);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Sleep()
|
|
{
|
|
Thread.Sleep(_workItemDuration);
|
|
}
|
|
|
|
private void spinMinThreads_Decrement(object sender, EventArgs eventArgs)
|
|
{
|
|
int minThreads = Step(txtMinThreads, 0, MaxThreads, -1);
|
|
if (_stp != null)
|
|
{
|
|
_stp.MinThreads = minThreads;
|
|
}
|
|
}
|
|
|
|
private void spinMinThreads_Increment(object sender, EventArgs eventArgs)
|
|
{
|
|
int minThreads = Step(txtMinThreads, 0, Convert.ToInt32(txtMaxThreads.Text), +1);
|
|
if (_stp != null)
|
|
{
|
|
_stp.MinThreads = minThreads;
|
|
}
|
|
}
|
|
|
|
private void spinMaxThreads_Decrement(object sender, EventArgs e)
|
|
{
|
|
int maxThreads = Step(txtMaxThreads, Convert.ToInt32(txtMinThreads.Text), 10, -1);
|
|
if (_stp != null)
|
|
{
|
|
_stp.MaxThreads = maxThreads;
|
|
}
|
|
}
|
|
|
|
private void spinMaxThreads_Increment(object sender, EventArgs e)
|
|
{
|
|
int maxThreads = Step(txtMaxThreads, 0, MaxThreads, +1);
|
|
usageControl1.Maximum = maxThreads;
|
|
usageHistoryControl1.Maximum = maxThreads;
|
|
if (_stp != null)
|
|
{
|
|
_stp.MaxThreads = maxThreads;
|
|
}
|
|
}
|
|
|
|
private void spinIdleTimeout_Decrement(object sender, EventArgs e)
|
|
{
|
|
Step(txtIdleTimeout, 0, 10, -1);
|
|
}
|
|
|
|
private void spinIdleTimeout_Increment(object sender, EventArgs e)
|
|
{
|
|
Step(txtIdleTimeout, 0, 10, +1);
|
|
}
|
|
|
|
private void spinWorkItemPerSec_Decrement(object sender, EventArgs e)
|
|
{
|
|
int workItemPerSec = _workItemPerSec;
|
|
_workItemPerSec = Step(txtWorkItemPerSec, 0, 10, -1);
|
|
if (workItemPerSec != _workItemPerSec)
|
|
{
|
|
_wakeupEvent.Set();
|
|
}
|
|
}
|
|
|
|
private void spinWorkItemPerSec_Increment(object sender, EventArgs e)
|
|
{
|
|
int workItemPerSec = _workItemPerSec;
|
|
_workItemPerSec = Step(txtWorkItemPerSec, 0, 10, +1);
|
|
if (workItemPerSec != _workItemPerSec)
|
|
{
|
|
_wakeupEvent.Set();
|
|
}
|
|
}
|
|
|
|
private void spinWorkItemDuration_Decrement(object sender, EventArgs e)
|
|
{
|
|
_workItemDuration = Step(txtWorkItemDuration, 0, 1000, -100);
|
|
}
|
|
|
|
private void spinWorkItemDuration_Increment(object sender, EventArgs e)
|
|
{
|
|
_workItemDuration = Step(txtWorkItemDuration, 0, 1000, +100);
|
|
}
|
|
|
|
private static int Step(TextBlock txtField, int minValue, int maxValue, int change)
|
|
{
|
|
int value = Convert.ToInt32(txtField.Text);
|
|
|
|
value += change;
|
|
|
|
if (value < minValue)
|
|
{
|
|
value = minValue;
|
|
}
|
|
|
|
if (value > maxValue)
|
|
{
|
|
value = maxValue;
|
|
}
|
|
|
|
txtField.Text = value.ToString();
|
|
|
|
return value;
|
|
}
|
|
|
|
}
|
|
} |