Wrapping StopWatch timing with a delegate or lambda?
How about extending the Stopwatch class?
public static class StopwatchExtensions
{
public static long Time(this Stopwatch sw, Action action, int iterations)
{
sw.Reset();
sw.Start();
for (int i = 0; i < iterations; i++)
{
action();
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
}
Then call it like this:
var s = new Stopwatch();
Console.WriteLine(s.Time(() => DoStuff(), 1000));
You could add another overload which omits the "iterations" parameter and calls this version with some default value (like 1000).
Can I tie an anonymous function to a Timer's tick event?
You're looking for Anonymous Methods:
myTimer.Tick += delegate (object sender, EventArgs e) {
MessageBox.Show("Hello world!");
};
You can also omit the parameters:
myTimer.Tick += delegate {
MessageBox.Show("Hello world!");
};
In C# 3.0, you can also use a Lambda Expression:
myTimer.Tick += (sender, e) => {
MessageBox.Show("Hello world!");
};
Helper class for performance tests using StopWatch class
Here is simple class, which can help you for measuring time of code block execution:
public class PerformanceTester : IDisposable
{
private Stopwatch _stopwatch = new Stopwatch();
private Action<TimeSpan> _callback;
public PerformanceTester()
{
_stopwatch.Start();
}
public PerformanceTester(Action<TimeSpan> callback) : this()
{
_callback = callback;
}
public static PerformanceTester Start(Action<TimeSpan> callback)
{
return new PerformanceTester(callback);
}
public void Dispose()
{
_stopwatch.Stop();
if (_callback != null)
_callback(Result);
}
public TimeSpan Result
{
get { return _stopwatch.Elapsed; }
}
}
Usage (just wrap code block with using of PerformanceTester
):
using (var tester = new PerformanceTester())
{
// code to test
MessageBox.Show(tester.Results.ToString());
}
If you declare tester variable before using
block, then stopwatch will stop automatically when you exit using
block, and results will be available for you:
PerformanceTester tester;
using (tester = new PerformanceTester())
SomeAction();
MessageBox.Show(tester.Results.ToString());
If you pass callback action to PerformanceTester
, then this action will be called at the end of using
statement, and elapsed time will be passed to callback:
using (PerformanceTester.Start(ts => MessageBox.Show(ts.ToString())))
SomeAction();
You can declare method, which will accept TimeSpan
and process results:
private void ProcessResult(TimeSpan span)
{
// log, show, etc
MessageBox.Show(span.ToString());
}
Usage becomes very clean:
using (PerformanceTester.Start(ProcessResult))
SomeAction();
Wrap a delegate in an IEqualityComparer
Ordinarily, I'd get this resolved by commenting @Sam on the answer (I've done some editing on the original post to clean it up a bit without altering the behavior.)
The following is my riff of @Sam's answer, with a [IMNSHO] critical fix to the default hashing policy:-
class FuncEqualityComparer<T> : IEqualityComparer<T>
{
readonly Func<T, T, bool> _comparer;
readonly Func<T, int> _hash;
public FuncEqualityComparer( Func<T, T, bool> comparer )
: this( comparer, t => 0 ) // NB Cannot assume anything about how e.g., t.GetHashCode() interacts with the comparer's behavior
{
}
public FuncEqualityComparer( Func<T, T, bool> comparer, Func<T, int> hash )
{
_comparer = comparer;
_hash = hash;
}
public bool Equals( T x, T y )
{
return _comparer( x, y );
}
public int GetHashCode( T obj )
{
return _hash( obj );
}
}
Make a method to return Execution Time of another Method
I've just created such a method to test performance in this SO question:
private static TimeSpan MeasureExecTime(Action action, int iterations)
{
action(); // warm up
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
action();
}
return sw.Elapsed;
}
Usage:
MeasureExecTime(() => DoSomething(5), 100000);
See 280Z28's answer if you don't want to test more than one iteration :-)
Store function for later use / delegate with undefined attributes
Whenever you need a delegate with unknown signature simply wrap it inside of an Action
(basically a parameter less void
delegate)
You could probably do something like
// For storing the callback
private Action _whenHaveAuthority;
// For storing the NetworkIdentity that requested authority
// In order to check back later if the event is for us
private NetworkIdentity _identity;
public void RequestAuthority(NetworkIdentity identity, Action whenHaveAuthority)
{
// Store identity and callback
_whenHaveAuthority = whenHaveAuthority;
_identity = identity;
CmdRequestNetworkAuthority(identity);
}
[Command]
private void CmdRequestNetworkAuthority(NetworkIdentity identity)
{
identity.AssignClientAuthority(base.connectionToClient);
Rpc_InformClientHasAuthority(identity);
}
// Server informs all clients
[ClientRpc]
private void Rpc_InformClientHasAuthority(NetworkIdentity identity)
{
// Check if we are the one that sent the request
if(_identity && _identity == identity)
{
// Execute the stored callback
_whenHaveAuthority?.Invoke();
// and reset
_identity = null;
_whenHaveAuthority = null;
}
}
And then you would pass in the callback like e.g.
public void CornerSpawnRequest(Vector3 spawnPosition, GameObject joinToObject)
{
NetworkIDRequest.instance.RequestAuthority(GetComponent<NetworkIdentity>(), () =>
{
NetworkCornerSpawn(spawnPosition, joinToObject);
});
}
[Command]
private void NetworkCornerSpawn(Vector3 spawnPosition, GameObject joinToObject)
{
CornerSpawnExecution(spawnPosition, joinToObject);
}
Note: Typed on smartphone but I hope the idea gets clear
Related Topics
Differencebetween Manualresetevent and Autoresetevent in .Net
Is Enabling Double Escaping Dangerous
How to Correctly Prefix a Word with "A" and "An"
How to Pass a Username/Password in the Header to a Soap Wcf Service
How to Read the Data in a Wav File to an Array
Control Cannot Fall Through from One Case Label
Watermark in System.Windows.Forms.Textbox
Convert from Binary Data to an Image Control in ASP.NET
When Should I Use Gc.Suppressfinalize()
C# Entity-Framework: How to Combine a .Find and .Include on a Model Object
Checking If a String Array Contains a Value, and If So, Getting Its Position
I Need a Event to Detect Internet Connect/Disconnect
How Does Comparison Operator Works with Null Int