Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyOsherove authored and RoyOsherove committed Jun 26, 2007
1 parent 23aa596 commit e5117e3
Show file tree
Hide file tree
Showing 8 changed files with 434 additions and 0 deletions.
19 changes: 19 additions & 0 deletions ThreadTester/Events/AutoResetEventEx.cs
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using System.Threading;

namespace Osherove.ThreadTester.Events
{
[ComVisible(true), HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
public class AutoResetEventEx : EventWaitHandleEx
{
// Methods
public AutoResetEventEx(bool initialState)
: base(initialState, EventResetMode.AutoReset)
{
}
}
}
148 changes: 148 additions & 0 deletions ThreadTester/Events/EventWaitHandleEx.cs
@@ -0,0 +1,148 @@
using System;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Threading;

namespace Osherove.ThreadTester.Events
{

[ComVisible(true), HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
public class EventWaitHandleEx : EventWaitHandle
{
public delegate void WaitDelegate(object sender, WaitEventArgs args);
public event WaitDelegate BeforeWaitCalled = delegate { };
public event EventHandler Closed = delegate { };

public EventWaitHandleEx(bool initialState, EventResetMode mode)
: base(initialState, mode)
{
}


public override bool WaitOne(TimeSpan timeout, bool exitContext)
{
bool cancel = false;
OnWait((int?) timeout.TotalMilliseconds, exitContext, ref cancel);
if (cancel)
{
return false;
}

return base.WaitOne(timeout, exitContext);
}

public override bool WaitOne(int millisecondsTimeout, bool exitContext)
{
bool cancel = false;
OnWait(millisecondsTimeout, exitContext, ref cancel);
if (cancel && allowWaitCanceling)
{
return false;
}
return base.WaitOne(millisecondsTimeout, exitContext);
}


public override bool WaitOne()
{
bool cancel = false;
OnWait(null, null,ref cancel);
if (cancel)
{
return false;
}
return base.WaitOne();
}


private bool allowWaitCanceling;

/// <summary>
/// Setting this to true will trigger the BeforeWaitCalled event
/// in a synchronized fasion. when false, the event is thrown in asyc (new thread).
/// </summary>
public bool AllowWaitCanceling
{
get { return allowWaitCanceling; }
set { allowWaitCanceling = value; }
}

private void TriggerWaitCalledNewThread(int? timeout, bool? exitContext, ref bool cancel)
{

WaitEventArgs args = new WaitEventArgs(timeout, exitContext);
Thread t = new Thread(new ThreadStart(delegate
{
SafeTrigger(BeforeWaitCalled, this, args);
if (args.CancelWait)
{
ArgumentException exception = new ArgumentException("You can't cancel a call to WaitOne() without setting AllowWaitCanceling to true");
ThreadManager.exceptions.Add(exception);
throw exception;
}
}));
t.Start();
}
private static void SafeTrigger(Delegate del, params object[] args)
{
// // return;
// del.DynamicInvoke(args);
// return;

foreach (Delegate callback in del.GetInvocationList())
{
try
{
callback.DynamicInvoke(args);
}
catch (Exception e)
{
// Console.WriteLine(e.ToString());
}
}
}
private void TriggerWaitCalledSameThread(int? timeout, bool? exitContext, ref bool cancel)
{
WaitEventArgs args = new WaitEventArgs(timeout, exitContext);
SafeTrigger(BeforeWaitCalled, this, args);
if (args.CancelWait)
{
cancel = true;
}
}
private int waiters;

public int Waiters
{
get { return waiters; }
set { waiters = value; }
}

private void OnWait(int? timeout, bool? exitContext, ref bool cancel)
{

waiters++;
if (allowWaitCanceling)
{
TriggerWaitCalledSameThread(timeout, exitContext, ref cancel);
if(cancel)
{
waiters--;
}
}
else
{
TriggerWaitCalledNewThread(timeout, exitContext, ref cancel);
}

}



}




}
18 changes: 18 additions & 0 deletions ThreadTester/Events/ManualResetEventEx.cs
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using System.Threading;

namespace Osherove.ThreadTester.Events
{
//
public class ManualResetEventEx : EventWaitHandleEx
{
public ManualResetEventEx(bool initialState)
: base(initialState, EventResetMode.ManualReset)
{
}
}
}
30 changes: 30 additions & 0 deletions ThreadTester/Events/UnhandledException.cs
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Osherove.ThreadTester.Events
{
public class UnhandledException:Exception
{
private object sender;
private UnhandledExceptionEventArgs args;

public UnhandledException(object sender, UnhandledExceptionEventArgs args)
{
this.sender = sender;
this.args = args;
}

public object Sender
{
get { return sender; }
set { sender = value; }
}

public UnhandledExceptionEventArgs Args
{
get { return args; }
set { args = value; }
}
}
}
47 changes: 47 additions & 0 deletions ThreadTester/Events/WaitEventArgs.cs
@@ -0,0 +1,47 @@
using System;

namespace Osherove.ThreadTester.Events
{
public class WaitEventArgs:EventArgs
{
private bool cancelwait;

public bool CancelWait
{
get { return cancelwait; }
set { cancelwait = value; }
}

private int? timeout;

public int? TimeOut
{
get { return timeout; }
set { timeout = value; }
}

private bool? exitContext;

public bool? ExitContext
{
get { return exitContext; }
set { exitContext = value; }
}

public WaitEventArgs()
{
}


public WaitEventArgs(int? timeout)
{
this.timeout = timeout;
}

public WaitEventArgs(int? timeout, bool? exitContext)
{
this.timeout = timeout;
this.exitContext = exitContext;
}
}
}
5 changes: 5 additions & 0 deletions ThreadTester/History.txt
@@ -0,0 +1,5 @@

1.00.1
----------
- Added ResetAbort() to threads to prevent ugly exceptions
- Added .StopWhenTrue() ability
55 changes: 55 additions & 0 deletions ThreadTester/Tests/EventWaitHandleExTests.cs
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Osherove.ThreadTester.Events;

namespace Osherove.ThreadTester.Tests
{
[TestFixture]
public class EventWaitHandleExTests
{
[Test]
// [ExpectedException(typeof(ArgumentException), "You can't cancel a call to WaitOne() without setting AllowWaitCanceling to true")]
public void WaitOne_CancelSetToTrueOnEvent_CanCancelWait()
{
AutoResetEventEx e = new AutoResetEventEx(false);
e.BeforeWaitCalled+=delegate(object sender, WaitEventArgs args)
{
args.CancelWait = true;
};
e.WaitOne(100, true);
Assert.AreEqual(1,ThreadManager.exceptions.Count);

}

[Test]
public void BeforeWaitCalled_Triggered()
{
AutoResetEventEx e = new AutoResetEventEx(false);
e.BeforeWaitCalled += delegate(object sender, WaitEventArgs args)
{
Assert.AreEqual(100,args.TimeOut);
Assert.AreEqual(true,args.ExitContext);
Console.WriteLine("wait({0},{1})", args.TimeOut, args.ExitContext);
};
bool result = e.WaitOne(100, true);
Assert.AreEqual(1, e.Waiters);
Console.WriteLine("done");
}

[Test]
public void BeforeWaitCalled_TriggeredAndCancenled()
{
AutoResetEventEx e = new AutoResetEventEx(false);
e.AllowWaitCanceling = true;
e.BeforeWaitCalled += delegate(object sender, WaitEventArgs args)
{
args.CancelWait = true;
};
bool result = e.WaitOne(1000, true);
Assert.AreEqual(0,e.Waiters);
Console.WriteLine("done");
}
}
}

0 comments on commit e5117e3

Please sign in to comment.