//******************************************************************************************************
// LogicalThread.cs - Gbtc
//
// Copyright © 2015, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://opensource.org/licenses/MIT
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 09/24/2015 - Stephen C. Wills
// Generated original version of source code.
// 02/16/2016 - J. Ritchie Carroll
// Changed default priority level to 1 - normal / lowest.
//
//******************************************************************************************************
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace GSF.Threading
{
///
/// Represents a set of statistics gathered about
/// the execution time of actions on a logical thread.
///
public class LogicalThreadStatistics
{
#region [ Members ]
// Fields
private TimeSpan m_maxExecutionTime;
private TimeSpan m_minExecutionTime;
private TimeSpan m_totalExecutionTime;
private long m_executionCount;
#endregion
#region [ Properties ]
///
/// Gets the execution time of the longest running action.
///
public TimeSpan MaxExecutionTime
{
get
{
return m_maxExecutionTime;
}
}
///
/// Gets the execution time of the shortest running action.
///
public TimeSpan MinExecutionTime
{
get
{
return m_minExecutionTime;
}
}
///
/// Gets the total execution time of all actions executed on the logical thread.
///
public TimeSpan TotalExecutionTime
{
get
{
return m_totalExecutionTime;
}
}
///
/// Gets the total number of actions executed on the logical thread.
///
public long ExecutionCount
{
get
{
return m_executionCount;
}
}
#endregion
#region [ Methods ]
///
/// Updates the statistics based on the execution time of a single action.
///
/// The execution time of the action.
internal void UpdateStatistics(TimeSpan executionTime)
{
if (m_executionCount == 0 || executionTime > m_maxExecutionTime)
m_maxExecutionTime = executionTime;
if (m_executionCount == 0 || executionTime < m_minExecutionTime)
m_minExecutionTime = executionTime;
m_totalExecutionTime += executionTime;
m_executionCount++;
}
#endregion
}
///
/// Represents a thread of execution to which
/// actions can be dispatched from other threads.
///
///
///
/// This class provides a simple alternative to synchronization primitives
/// such as wait handles and locks. Actions dispatched to a logical thread
/// will be processed synchronously as though it was executed as consecutive
/// method calls. All such actions can be dispatched from any thread in the
/// system so method calls coming from multiple threads can be easily
/// synchronized without locks, loops, wait handles, or timeouts.
///
///
///
/// Note that the implements its own
/// thread pool to execute tasks pushed to logical threads. Executing
/// long-running processes or using synchronization primitives with high
/// contention or long timeouts can hinder the logical thread scheduler's
/// ability to schedule the actions of other logical threads. Like other
/// thread pool implementations, you can mitigate this by increasing the
/// maximum thread count of the logical thread scheduler, however it is
/// recommended to avoid using synchronization primitives and instead
/// synchronize those operations by running them as separate actions on
/// the same logical thread.
///
///
public class LogicalThread
{
#region [ Members ]
// Events
///
/// Handler for unhandled exceptions on the thread.
///
public event EventHandler> UnhandledException;
// Fields
private LogicalThreadScheduler m_scheduler;
private ConcurrentQueue[] m_queues;
private Dictionary