mirror of
https://github.com/farcasclaudiu/SmartThreadPool.git
synced 2026-06-22 11:01:28 +03:00
Moved to VS 2012 + Added support to Windows Phone
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user