На вашем втором графике есть выбросы, которые влияют на расчет.
Из документов вы можете посмотреть на параметр whis
:
whis: float, необязательный
Доля IQR после минимума и высокие квартили, чтобы продлить сюжет усы.
Точки за пределами этого диапазона будут обозначаться как выбросы.
blockquote>Попробуйте с большими значениями для
whis
(2.0
,5.0
,10.0
, ...), чтобы ваши точки данных всегда попадали в квартили.
Некоторые незначительные изменения в отличном ответе Pop Catalin:
Были перегрузки добавлено для поддержки сигнального рабочего для отмены выполнения:
public static T Invoke<T> (Func<CancelEventArgs, T> function, TimeSpan timeout) {
if (timeout.TotalMilliseconds <= 0)
throw new ArgumentOutOfRangeException ("timeout");
CancelEventArgs args = new CancelEventArgs (false);
IAsyncResult functionResult = function.BeginInvoke (args, null, null);
WaitHandle waitHandle = functionResult.AsyncWaitHandle;
if (!waitHandle.WaitOne (timeout)) {
args.Cancel = true; // flag to worker that it should cancel!
/* •————————————————————————————————————————————————————————————————————————•
| IMPORTANT: Always call EndInvoke to complete your asynchronous call. |
| http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.80).aspx |
| (even though we arn't interested in the result) |
•————————————————————————————————————————————————————————————————————————• */
ThreadPool.UnsafeRegisterWaitForSingleObject (waitHandle,
(state, timedOut) => function.EndInvoke (functionResult),
null, -1, true);
throw new TimeoutException ();
}
else
return function.EndInvoke (functionResult);
}
public static T Invoke<T> (Func<T> function, TimeSpan timeout) {
return Invoke (args => function (), timeout); // ignore CancelEventArgs
}
public static void Invoke (Action<CancelEventArgs> action, TimeSpan timeout) {
Invoke<int> (args => { // pass a function that returns 0 & ignore result
action (args);
return 0;
}, timeout);
}
public static void TryInvoke (Action action, TimeSpan timeout) {
Invoke (args => action (), timeout); // ignore CancelEventArgs
}
Мы используем такой код в большой степени в production n:
var result = WaitFor<Result>.Run(1.Minutes(), () => service.GetSomeFragileResult());
Реализация с открытым кодом, эффективно работает даже в сценариях параллельных вычислений и доступен как часть Lokad Shared Libraries
/// <summary>
/// Helper class for invoking tasks with timeout. Overhead is 0,005 ms.
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
[Immutable]
public sealed class WaitFor<TResult>
{
readonly TimeSpan _timeout;
/// <summary>
/// Initializes a new instance of the <see cref="WaitFor{T}"/> class,
/// using the specified timeout for all operations.
/// </summary>
/// <param name="timeout">The timeout.</param>
public WaitFor(TimeSpan timeout)
{
_timeout = timeout;
}
/// <summary>
/// Executes the spcified function within the current thread, aborting it
/// if it does not complete within the specified timeout interval.
/// </summary>
/// <param name="function">The function.</param>
/// <returns>result of the function</returns>
/// <remarks>
/// The performance trick is that we do not interrupt the current
/// running thread. Instead, we just create a watcher that will sleep
/// until the originating thread terminates or until the timeout is
/// elapsed.
/// </remarks>
/// <exception cref="ArgumentNullException">if function is null</exception>
/// <exception cref="TimeoutException">if the function does not finish in time </exception>
public TResult Run(Func<TResult> function)
{
if (function == null) throw new ArgumentNullException("function");
var sync = new object();
var isCompleted = false;
WaitCallback watcher = obj =>
{
var watchedThread = obj as Thread;
lock (sync)
{
if (!isCompleted)
{
Monitor.Wait(sync, _timeout);
}
}
// CAUTION: the call to Abort() can be blocking in rare situations
// http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx
// Hence, it should not be called with the 'lock' as it could deadlock
// with the 'finally' block below.
if (!isCompleted)
{
watchedThread.Abort();
}
};
try
{
ThreadPool.QueueUserWorkItem(watcher, Thread.CurrentThread);
return function();
}
catch (ThreadAbortException)
{
// This is our own exception.
Thread.ResetAbort();
throw new TimeoutException(string.Format("The operation has timed out after {0}.", _timeout));
}
finally
{
lock (sync)
{
isCompleted = true;
Monitor.Pulse(sync);
}
}
}
/// <summary>
/// Executes the spcified function within the current thread, aborting it
/// if it does not complete within the specified timeout interval.
/// </summary>
/// <param name="timeout">The timeout.</param>
/// <param name="function">The function.</param>
/// <returns>result of the function</returns>
/// <remarks>
/// The performance trick is that we do not interrupt the current
/// running thread. Instead, we just create a watcher that will sleep
/// until the originating thread terminates or until the timeout is
/// elapsed.
/// </remarks>
/// <exception cref="ArgumentNullException">if function is null</exception>
/// <exception cref="TimeoutException">if the function does not finish in time </exception>
public static TResult Run(TimeSpan timeout, Func<TResult> function)
{
return new WaitFor<TResult>(timeout).Run(function);
}
}
. Этот код все еще содержит ошибки, вы можете попробовать эту небольшую тестовую программу:
static void Main(string[] args) {
// Use a sb instead of Console.WriteLine() that is modifying how synchronous object are working
var sb = new StringBuilder();
for (var j = 1; j < 10; j++) // do the experiment 10 times to have chances to see the ThreadAbortException
for (var ii = 8; ii < 15; ii++) {
int i = ii;
try {
Debug.WriteLine(i);
try {
WaitFor<int>.Run(TimeSpan.FromMilliseconds(10), () => {
Thread.Sleep(i);
sb.Append("Processed " + i + "\r\n");
return i;
});
}
catch (TimeoutException) {
sb.Append("Time out for " + i + "\r\n");
}
Thread.Sleep(10); // Here to wait until we get the abort procedure
}
catch (ThreadAbortException) {
Thread.ResetAbort();
sb.Append(" *** ThreadAbortException on " + i + " *** \r\n");
}
}
Console.WriteLine(sb.ToString());
}
}
Возникла гонка. Совершенно очевидно, что исключение ThreadAbortException возникает после вызова метода WaitFor
. Я не нашел надежного способа исправить это, однако с помощью того же теста я не могу воспроизвести какую-либо проблему с принятым ответом TheSoftwareJedi .
А как насчет использования Thread.Join (int timeout)?
public static void CallWithTimeout(Action act, int millisecondsTimeout)
{
var thread = new Thread(new ThreadStart(act));
thread.Start();
if (!thread.Join(millisecondsTimeout))
throw new Exception("Timed out");
}