GithubHelp home page GithubHelp logo

methodtimer's Introduction

AppVeyor Chat on Gitter NuGet Status Patrons on Open Collective

Extensible tool for weaving .net assemblies

Manipulating the IL of an assembly as part of a build requires a significant amount of plumbing code. This plumbing code involves knowledge of both the MSBuild and Visual Studio APIs. Fody attempts to eliminate that plumbing code through an extensible add-in model.

This is the codebase of core Fody engine. For more information on the larger Fody project see https://github.com/Fody/Home.

See Milestones for release notes.

Already a Patron? skip past this section

Community backed

Fody requires significant effort to maintain. As such it relies on financial support to ensure its long term viability.

It is expected that all developers using Fody become a Patron on OpenCollective.

See Licensing/Patron FAQ for more information.

Gold Sponsors

Support this project by becoming a Gold Sponsor. A large company logo will be added here with a link to your website.

PostSharp

Silver Sponsors

Support this project by becoming a Silver Sponsor. A medium company logo will be added here with a link to your website.

G-Research Particular Software

Bronze Sponsors

Support this project by becoming a Bronze Sponsor. The company avatar will show up here with a link to your OpenCollective Profile.

Patrons and sponsors

Thanks to all the backers and sponsors! Support this project by becoming a patron.

Documentation and Further Learning

Contributors

This project exists thanks to all the people who contribute.

methodtimer's People

Contributors

dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar geertvanhorrik avatar kataras12 avatar ltrzesniewski avatar simoncropp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

methodtimer's Issues

Empty async Task method no longer working

Just updated MethodTimer on a project. Allthough it's silly (I agree), it should work:

[Time]
public virtual async Task InitializeBeforeShowingSplashScreen()
{
}

Before it worked correctly, now PEVerify throws this at me:

6> Verifying assembly
6>MSBUILD : error : Fody: PEVerify of the assembly failed.
6>MSBUILD : error : 
6>MSBUILD : error : Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.33440
6>MSBUILD : error : Copyright (c) Microsoft Corporation. All rights reserved.
6>MSBUILD : error : 
6>MSBUILD : error : [IL]: Error: [C:\CI_WS\Ws\78464\Source\Orchestra\output\release\NET40\Orchestra.Shell.Ribbon.Fluent\Orchestra.Shell.Ribbon.Fluent.dll : Orchestra.Services.ApplicationInitializationServiceBase+<InitializeBeforeShowingSplashScreen>d__0::MoveNext][offset 0x0000004C] fallthru the end of an exception block(Error: 0x80131835)
6>MSBUILD : error : [IL]: Error: [C:\CI_WS\Ws\78464\Source\Orchestra\output\release\NET40\Orchestra.Shell.Ribbon.Fluent\Orchestra.Shell.Ribbon.Fluent.dll : Orchestra.Services.ApplicationInitializationServiceBase+<InitializeBeforeCreatingShell>d__2::MoveNext][offset 0x0000004C] fallthru the end of an exception block(Error: 0x80131835)
6>MSBUILD : error : [IL]: Error: [C:\CI_WS\Ws\78464\Source\Orchestra\output\release\NET40\Orchestra.Shell.Ribbon.Fluent\Orchestra.Shell.Ribbon.Fluent.dll : Orchestra.Services.ApplicationInitializationServiceBase+<InitializeAfterCreatingShell>d__4::MoveNext][offset 0x0000004C] fallthru the end of an exception block(Error: 0x80131835)
6>MSBUILD : error : [IL]: Error: [C:\CI_WS\Ws\78464\Source\Orchestra\output\release\NET40\Orchestra.Shell.Ribbon.Fluent\Orchestra.Shell.Ribbon.Fluent.dll : Orchestra.Services.ApplicationInitializationServiceBase+<InitializeBeforeShowingShell>d__6::MoveNext][offset 0x0000004C] fallthru the end of an exception block(Error: 0x80131835)
6>MSBUILD : error : [IL]: Error: [C:\CI_WS\Ws\78464\Source\Orchestra\output\release\NET40\Orchestra.Shell.Ribbon.Fluent\Orchestra.Shell.Ribbon.Fluent.dll : Orchestra.Services.ApplicationInitializationServiceBase+<InitializeAfterShowingShell>d__8::MoveNext][offset 0x0000004C] fallthru the end of an exception block(Error: 0x80131835)
6>MSBUILD : error : 5 Error(s) Verifying C:\CI_WS\Ws\78464\Source\Orchestra\output\release\NET40\Orchestra.Shell.Ribbon.Fluent\Orchestra.Shell.Ribbon.Fluent.dll
6>MSBUILD : error : 
6> Finished verification in 257ms.

It's not a big deal (it's better to remove them anyway), but I want to make sure that nothing else is broken during the async refactoring?

Async method that throws Exception not working

You should already be a Patron

I am testing Fody to see if we can use it in our project and if so, we will become a patron. If this means that I cannot raise an issue, please ignore this.

Describe the issue

I have a simple async function that awaits a Task and then throws an exception afterwards. When I wrap this with [Time] there are two things that go weird a) the total time is incorrect (the await time is not taken into account) b) the time is written to the console twice.

Minimal Repro

https://github.com/adrianignat13/MethodTimerSample

From output:
Program.AsyncDelay 12ms
Exception thrown: 'System.Exception' in MethodTimerSample.exe
Program.AsyncDelay 12ms

Expected output (manual weaving)
Program.AsyncDelayWithTimer 00:00:01.0291857ms
Exception thrown: 'System.AggregateException' in mscorlib.dll

Shared MethodTimeLogger interceptor class

My solution has a web application project and numerous referenced projects. I would like to implement the MethodTimeLogger class in my utility project / assembly which is referenced by most of the others, such that I can use the [Time] attribute within any of the projects, and the MethodTimeLogger implementation from the shared assembly will be what is injected for all of them. It seems that currently the MethodTimeLogger signature is only searched for within the same assembly as a Time attribute instance, is that correct? I could copy it to each project and have it delegate the actual logging to my shared project, but that seems unpleasant. Am I using this correctly? Thanks!

CLR detected an invalid program when using [Timer] on 'public async void' method

I am using .NET 4.0 with the Async Targeting Pack in Visual Studio 2012.

With a method like this:

[Time]
public async void Delay()
{
     await TaskEx.Delay(1000);
}

Calls to it such as:

var temp = IocContainer.Resolve<IService>();
temp.Delay();

Fail with an InvalidProgramException message of "Common Language Runtime detected an invalid program."

From what I can tell this is an issue specifically with methods that have a signature of 'async void'. My reason for using 'async void' is that I want to measure the time that an async method takes to execute but I do not want to hold up the caller from continuing its execution.

As a side note, I notice a lost of errors with Telerik JustDecompile trying to parse the weaved class. Even when I remove that 'Delay' method, there are still errors in JustDecompile. These errors are only in the classes that are using [Time] with async.

Fody.MethodTimer doesn't work when I compile the source code

So, I downloaded the Fody.MethodTimer, updated the nuget packages and compiled the solution.

Next, I created a Library project and added the [Time] attribut on a method.

I opened the .dll with dotPeek, but the generated code was exactly the same. and nothing was weaved ?

How can I get that to work without downloading the Nuget package ?

Thanks in advance :)

Incorrect method execution time in MethodTimeLogger

Where it is clear that the below content has not read, the issue is likely to be closed with "please read the template". Please don't take offense at this. It is simply a time management decision. When someone raises an issue, without reading the template, then often too much time is spent going back and forth to obtain information that is outlined below.

You should already be a Patron

To be using Fody you should be a Patron. See Licensing/Patron FAQ. With that in mind, it is assumed anyone raising an issue is already a Patron. As such your GitHub Id may be verified against the OpenCollective contributors. This process will depend on the issue quality, your circumstances, and the impact on the larger user base.

Preamble

Questions specific to IL manipulation should be placed on Stack Overflow or the Cecil Forum.

General questions about Fody or weavers should be placed on Stack Overflow or the Fody Gitter room

Where relevant, ensure you are using the current stable versions of the following:

  • Fody (note for this you need an explicit NuGet reference to Fody in your csproj)
  • Any Fody weavers being used
  • Visual Studio
  • .NET Core SDK

Any code or stack traces must be properly formatted with GitHub markdown.

Describe the issue

The method execution time(long milliseconds) passed in to the Log method in MethodTimeLogger is incorrect when MethodTimeLogger is not in the same project. This seems to only happen in .net core projects. I have another project targeting .net framework 451 with pretty much the same setup and dont have this issue.

Minimal Repro

https://github.com/satuday/methodTimerTest

Submit a PR that fixes the bug

Submit a Pull Request (PR) that fixes the bug. Include in this PR a test that verifies the fix. If you were not able to fix the bug, a PR that illustrates your partial progress will suffice. If you prefer someone else fix this bug for you, please donate to the Fody OpenCollective and include a note to that effect in this issue.

Enhancement request (Timespan instead of milliseconds)

Hi, I'm playing around with Fody and came across MethodTimer. It looks almost exactly what I want.

I have a process that performs operations on 1-2 million items. There are about 8 methods that are called on each item. I would like to time the total time it takes in each method for the whole set (i.e. aggregate the individual timings). The problem I have is that the custom intercepter does not support enough precision (by using long milliseconds). Most of my individual calls will be in the sub-millisecond range, which would return 0, so even adding up timings for 2,000,000 iterations would still show 0.

public static class MethodTimeLogger
{
    public static void Log(MethodBase methodBase, long milliseconds)
    {
        //Do some logging here
    }
}

What do you think about providing an overload like so:

public static class MethodTimeLogger
{
    public static void Log(MethodBase methodBase, Timespan elapsed)
    {
        Debug.WriteLine("Elapsed ticks: {0}", elapsed.Ticks);
    }
}

This would allow more precision and flexibility. In my case, the implementation would look something like this:

public static class MethodTimeLogger
{
    public static Dictionary<string, long> Counters = new Dictionary<string, long>();
    public static void Log(MethodBase methodBase, TimeSpan elapsed)
    {
        if (Counters.ContainsKey(methodBase.Name))
        {
            Counters[methodBase.Name] += elapsed.Ticks;
        }
        else
        {
            Counters[methodBase.Name] = elapsed.Ticks;
        }
    }
}

Thoughts? I would be happy to implement it and create a pull request.

Stopwatch.StartNew() allocation

Stopwatch is a class that allocates on the heap. Acquiring the elapsed time is simple math and does not require allocation.

A simple way to fix this is:

/// <summary>
/// Simple <see langword="struct"/> for capturing ticks instead of allocating a Stopwatch.
/// </summary>
public readonly struct Timestamp
{
    /// <summary>
    /// Constructs a <see cref="Timestamp"/> using the provided <paramref name="value"/>.
    /// </summary>
    public Timestamp(long value) => Value = value;

    /// <summary>
    /// Constructs a <see cref="Timestamp"/> by calling <see cref="Stopwatch.GetTimestamp"/>.
    /// </summary>
    public Timestamp()
        : this(Stopwatch.GetTimestamp()) { }

    /// <summary>
    /// The tick value that this represents.
    /// </summary>
    public long Value { get; }

    /// <summary>
    /// The <see cref="TimeSpan"/> value based on the number of ticks that have passed since this was created.
    /// </summary>
    public TimeSpan Elapsed
        => new(Stopwatch.GetTimestamp() - Value);

    /// <summary>
    /// Static shortcut for creating a new <see cref="Timestamp"/>.
    /// </summary>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static Timestamp New() => new();
}

I tried to integrate this but Stopwatch occurs too many times in this repo and in places that my attempt may simply be ineffective.

By switching from

var stopwatch = Stopwatch.StartNew();

to

var stopwatch = Timestamp.New();
// and eliminate the stopwatch.Stop() call.

You'll get the same result but with no allocation.

Adding a new struct might be problematic, but you can easily see how you could just do this instead:

var timestamp = Stopwatch.GetTimestamp();
/// code being measured.
var elapsed = new TimeSpan(Stopwatch.GetTimestamp() - timestamp);

Please update the format so it excludes this parameter when building in Release mode

Hey guys!

First of all, thank you for awesome work!

I am having trouble when building my .net core 7 app in Release mode, basically, I have this:

 [Time("Inserted {x}")]
    private async Task InsertGame(long? x, Game game)

When I debug it, it works like a charm, but, when I try to create a Release build, it throws this error:
Fody/MethodTimer: Parameter 'x' is not available on the async state machine. Probably it has been optimized away by the compiler. Please update the format so it excludes this parameter.

Tried googling but couldn't find anything on this.

Can you guys please advise what to do from here?

Thanks!

Fall back to debug if no trace

History: worked perfect until yesterday or so

Now I get this on a UWP project:

Severity	Code	Description	Project	File	Line	Suppression State
Error		Fody: An unhandled exception occurred:
Exception:
Could not find type 'Trace'.
StackTrace:
   at CecilExtensions.Type(List`1 types, String name) in C:\projects\methodtimer\MethodTimer.Fody\CecilExtensions.cs:line 148
   at ModuleWeaver.FindReferences() in C:\projects\methodtimer\MethodTimer.Fody\ReferenceFinder.cs:line 31
   at ModuleWeaver.Execute() in C:\projects\methodtimer\MethodTimer.Fody\ModuleWeaver.cs:line 37
   at lambda_method(Closure , Object )
   at InnerWeaver.ExecuteWeavers() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 182
   at InnerWeaver.Execute() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 87
Source:
MethodTimer.Fody
TargetSite:
Mono.Cecil.TypeDefinition Type(System.Collections.Generic.List`1[Mono.Cecil.TypeDefinition], System.String)	

Start Method Message

I would like to have a message at the start of the method, as method start, other async methods execute, and it causes confusion in the call train.

I tried to update the AsyncMethodProcessor within the InjectStopWatchStart - after a couple of hours understanding the flow....

I tried to add these two lines (for what its worth)
//todo: write method start time message
Instruction.Create(OpCodes.Ldstr, string.Concat(Method.FullName,"-Start") ),
Instruction.Create(OpCodes.Call, ModuleWeaver.TraceWriteLineMethod)

but after I compiled, and incorporated in to my solution - it seems that I broke the entire Nuget package. I'm not looking for someone to do the work for me, but I would like to know If I'm on the right track, and how to incorporate a new version into my project without loosing all reference resolution to the Time attribute.

I also tried adding this constructuor on the time attribute:
using a optional parameter to avoid a change in parameter or method signature:

public TimeAttribute(string format, bool WriteStartMessage = false)
{
}

but i didn't get as far in understanding how the MethodTimer uses either of these CTOR....

I'm new to Fody, but aware of what IL weaving, just never really got into it.

Regards
RIchard

Not an issue, more a question

So I have been trying to use MethodDecoratorEx.Fody to help with the logging in my application. Now currently I am unable to get the MethodDecoratorEx.Fody to play nicely with asynchronous methods and have opened an issue on this. However, what I really need is something that has both the Init, OnEntry, OnExit, OnException with the awesomeness that this package provide in the method timer. Because for some reason that I have no idea what the Method Timer works properly with asynchronous methods How I expect it too but the MethodDecoratorEx does not. (My guess is it lies in the finally block, but that's just my idea.)

Does anyone know if I can achieve something similar to a MethodDecoratorTimer mesh of a add-in? I have tried looking at the source code for things but it is really confusing to me. Maybe if someone could point me in the right direction of what I should do that would be great and I could fork either this project or the MethodDecoratorEx project and adds things into it.

Thanks in advance!

Write to Trace instead of Debug

so instead of

public void MyMethod()
{
    var stopwatch = Stopwatch.StartNew();
    try
    {
        //Some code u are curious how long it takes
        Console.WriteLine("Hello");
    }
    finally
    {
        stopwatch.Stop();
        Debug.WriteLine("MyClass.MyMethod " + stopwatch.ElapsedMilliseconds + "ms");
    }
}

it will do this

public void MyMethod()
{
    var stopwatch = Stopwatch.StartNew();
    try
    {
        //Some code u are curious how long it takes
        Console.WriteLine("Hello");
    }
    finally
    {
        stopwatch.Stop();
        Trace.WriteLine("MyClass.MyMethod " + stopwatch.ElapsedMilliseconds + "ms");
    }
}

Fody: An unhandled exception occurred in a UWP project

Trying to get MethodTimer to work in a UWP project, getting this at build:

1>MSBUILD : error : Fody: An unhandled exception occurred:
1>MSBUILD : error : Exception:
1>MSBUILD : error : Failed to read C:\Users\igor\.nuget\packages\Microsoft.NETCore.Runtime.CoreCLR-arm\1.0.0\runtimes\win8-arm\native\clretwrc.dll. Format of the executable (.exe) or library (.dll) is invalid.
1>MSBUILD : error : StackTrace:
1>MSBUILD : error :    at ModuleWeaver.ReadModule(String referencePath) in c:\projects\methodtimer\Fody\InterceptorFinder.cs:line 104
1>MSBUILD : error :    at ModuleWeaver.FindInterceptor() in c:\projects\methodtimer\Fody\InterceptorFinder.cs:line 30
1>MSBUILD : error :    at ModuleWeaver.Execute() in c:\projects\methodtimer\Fody\ModuleWeaver.cs:line 27
1>MSBUILD : error :    at lambda_method(Closure , Object )
1>MSBUILD : error :    at InnerWeaver.ExecuteWeavers() in c:\ConsoleBuildAgent\work\ed448661dbb30d2e\FodyIsolated\InnerWeaver.cs:line 164
1>MSBUILD : error :    at InnerWeaver.Execute() in c:\ConsoleBuildAgent\work\ed448661dbb30d2e\FodyIsolated\InnerWeaver.cs:line 82
1>MSBUILD : error : Source:
1>MSBUILD : error : MethodTimer.Fody
1>MSBUILD : error : TargetSite:
1>MSBUILD : error : Mono.Cecil.ModuleDefinition ReadModule(System.String)
1>MSBUILD : error : Format of the executable (.exe) or library (.dll) is invalid.
1>MSBUILD : error : StackTrace:
1>MSBUILD : error :    at Mono.Cecil.PE.ImageReader.ReadOptionalHeaders(UInt16& subsystem, UInt16& dll_characteristics)
1>MSBUILD : error :    at Mono.Cecil.PE.ImageReader.ReadImage()
1>MSBUILD : error :    at Mono.Cecil.PE.ImageReader.ReadImageFrom(Stream stream)
1>MSBUILD : error :    at Mono.Cecil.ModuleDefinition.ReadModule(Stream stream, ReaderParameters parameters)
1>MSBUILD : error :    at Mono.Cecil.ModuleDefinition.ReadModule(String fileName, ReaderParameters parameters)
1>MSBUILD : error :    at ModuleWeaver.ReadModule(String referencePath) in c:\projects\methodtimer\Fody\InterceptorFinder.cs:line 99
1>MSBUILD : error : Source:
1>MSBUILD : error : Mono.Cecil
1>MSBUILD : error : TargetSite:
1>MSBUILD : error : Void ReadOptionalHeaders(UInt16 ByRef, UInt16 ByRef)
1>MSBUILD : error : 

Support {this} in the message

Today I was playing with this, but couldn't use {this} in the method timer message. Obviously {this} is not possible in static methods, and for async methods we need to add some magic, but it should all be possible.

Happy to implement it myself if you agree this is a new fantastic addition to an already fantastic feature!

Measure performance for overriden methods

Hi. I have following scenario.

class Parent
{
[Time]
virtual SomeMethod()
}

In some cases I need to override SomeMethod as below and measure performance.

class Child:Parent
{
[Time]
override SomeMethod()
}

How can I only keep only overriden method's performance data.

Convert to .NET Standard

I think it's time to leave PCL behind us and drop all crap (e.g. Silverlight, etc) ms has delivered over the years.

Happy to PR.

Inject custom destination for elapsed time.

Hi, can we inject custom destination for elapsed time. From examples it seems like we can only add trace logs. But i want to store elapsed time in somewhere else. Can we do that?

Support method timing of vb.net async methods

Describe the issue

Fix crash when adding Time attribute to Async methods on vb.net assemblies

Minimal Repro

Add below to a vb.net assembly

    <MethodTimer.Time>
    Private Async Function Test() As Task
        Await Task.Delay(1500)
    End Function

build, causes below exception

Severity	Code	Description	Project	File	Line	Suppression State
Error		Fody: An unhandled exception occurred:
Exception:
Failed to execute weaver C:\Users\x\.nuget\packages\methodtimer.fody\3.1.2\build\..\weaver\MethodTimer.Fody.dll
Type:
System.Exception
StackTrace:
   at InnerWeaver.ExecuteWeavers() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 210
   at InnerWeaver.Execute() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 111
Source:
FodyIsolated
TargetSite:
Void ExecuteWeavers()
An error occurred processing 'System.Threading.Tasks.Task WindowsApp6.Form1::Form1_Load(System.Object,System.EventArgs)'. Error: Sequence contains no elements
Type:
System.Exception
StackTrace:
   at AsyncMethodProcessor.Process()
   at ModuleWeaver.ProcessMethod(MethodDefinition method)
   at ModuleWeaver.ProcessAssembly()
   at ModuleWeaver.Execute()
   at InnerWeaver.ExecuteWeavers() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 198
Source:
MethodTimer.Fody
TargetSite:
Void Process()
Sequence contains no elements
Type:
System.InvalidOperationException
StackTrace:
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at AsyncMethodProcessor.InnerProcess()
   at AsyncMethodProcessor.Process()
Source:
System.Core
TargetSite:
TSource First[TSource](System.Collections.Generic.IEnumerable`1[TSource])	WindowsApp6			

Make an effort to fix the bug

#325

Usage with UnmanagedFunctionPointer

Hi, in a project with 3rd party library, that is supplied in form of DLL+C# class
To allow for multiple dll instances, i use FunctionLoader described in my post on SO, https://stackoverflow.com/a/71514895/492624

So basically, constructor of said library interface/class is full of FunctionLoader.LoadFunction<MethodDefinition>(LibraryPath, "MethodDefinition") which just obtains the actual function from DLL copy and provides a way to call the method

My feature-proposal, or usage question, is whether it'd be possible to use MethodTimer for delegate, the reference to function (result of Marshal.GetDelegateForFunctionPointer ) or different approach, other than creating proxy class/implementation, that'd have all the functions wrapped and annotated with [Time]

Sample from current library usage

    // in constructor
    Startup = FunctionLoader.LoadFunction<_Startup>(LibraryName, "Startup");


    // outside of constructor
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate Int32 _Startup(UInt32 VersionNumber);

    public _Startup Startup;

FieldAccessException when using Blazor and generic async methods

When trying to trace some methods in Blazor (WASM) in overridden methods, I get a "FieldAccessException".

NetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer ]  Unhandled exception rendering component:  Field `<GetUserAsync>d__2`1:methodTimerMessage' is inaccessible from method `MyApp.UI.Services.MyAppUserManager/<GetUserAsync>d__2`1<Blorc.OpenIdConnect.User`1<Blorc.OpenIdConnect.Profile>>:StopMethodTimerStopwatch ()'
 
 System.FieldAccessException: Field `<GetUserAsync>d__2`1:methodTimerMessage' is inaccessible from method `MyApp.UI.Services.MyAppUserManager/<GetUserAsync>d__2`1<Blorc.OpenIdConnect.User`1<Blorc.OpenIdConnect.Profile>>:StopMethodTimerStopwatch ()'

I am trying to create a repro with unit tests for this.

Some async methods throw InvalidOperationException

Describe the issue

With the new update, some (not all!) methods throw this exception:

System.InvalidOperationException: 'Could not execute the method because either the method itself or the containing type is not fully instantiated.'

Minimal Repro

This happens to Orchestra. I will try to figure out what exactly is happening and why it's causing issues.

Make an effort to fix the bug

Working on it!

[Time] on async methods prints two times, neither as expected

Using this code:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    TwoSecondDelay();
}

[Time]
private async void TwoSecondDelay()
{
    await Task.Delay(2000);
}

I would expect that one entry would be sent to Debug.Writeline and that entry would be 2000+ ms. Rather, the output is:

MainWindow.TwoSecondDelay 1ms
MainWindow.TwoSecondDelay 0ms

The first time output is displayed quickly, the second output is displayed after the 2000ms delay.

Debugging: This occurs with .NET 4.5 and .NET 4.0 + Async Targeting Pack. It occurs with 'private async void' and 'private async Task'.
The IL emitted for this method is:

private async void TwoSecondDelay()
{
    MainWindow.u003cTwoSecondDelayu003ed__0 variable.u003cu003e4__this = this;
    variable.u003cu003et__builder = AsyncVoidMethodBuilder.Create();
    variable.u003cu003e1__state = -1;
    AsyncVoidMethodBuilder u003cu003et_builder = variable.u003cu003et__builder;
    u003cu003et_builder.Start<MainWindow.u003cTwoSecondDelayu003ed__0>(ref variable);
}

I cannot dig farther into that IL b/c every link I click in JustDecompile takes me nowhere. If it helps, when I had my own Timing logic for async methods I implemented it with 'using' statements and it worked well. The Stopwatch would start in the PerformanceTimer constructor and when Dispose was called, the timer would stop and print its output.

public async void TwoSecondDelay()
{
    using(new PerformanceTimer())
    {
        await Task.Delay(2000);
    }
}

Add support for calling local log method

If you add support for calling a local instance method or just using a local ILogger variable.

This would make Frody.MethodTimer much more IOC friendly and a blizz to use with .net core!

Then one could write

[Time]
class Class1
{
    ILogger<Class1> logger;
    public Class1(ILogger<Class1> logger)
    {
        this.logger = logger;
    }

    public void Test()
    {
        Thread.Sleep(1000);
    }
}

Or if using ILogger is no option

[Time]
class Class1
{
    ILogger<Class1> logger;
    public Class1(ILogger<Class1> logger)
    {
        this.logger = logger;
    }

    public void Log(MethodBase methodBase, long milliseconds, string message)
    {
        logger.LogTrace("logic here");
    }

    public void Test()
    {
        Thread.Sleep(1000);
    }
}

Local functions

C# local functions looks like not supported? There is no logging found for it.

Invalid characters in path exception when building with MSBuild

I have a project that uses Fody.PropertyChanged. It builds fine in VS2015, but when I use MSBuild it fails:

Any idea what causes this ?

C:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe "D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj" /toolsVersion:14.0 /verbosity:quiet /p:WarningLevel=0 /p:Configuration=Release /p:SolutionDir="D:\projects\MyCompany.MessageHandler\"
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.

MSBUILD : error : Fody: An unhandled exception occurred:\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error : Exception:\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error : Invalid characters in path.\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error : StackTrace:\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error :    bij System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.
Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error :    bij System.IO.Path.Combine(String path1, String path2)\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHu
b.Installer.csproj]
MSBUILD : error :    bij ConfigFileFinder.FindWeaverConfigs(String solutionDirectoryPath, String projectDirectory, ILogger logger) in c:\ConsoleBuildAgent\w
ork\ed448661dbb30d2e\Fody\ConfigFileFinder.cs:regel 17\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error :    bij Processor.Inner() in c:\ConsoleBuildAgent\work\ed448661dbb30d2e\Fody\Processor.cs:regel 66\r [D:\projects\MyCompany.MessageHandler\src\C
evi.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error :    bij Processor.Execute() in c:\ConsoleBuildAgent\work\ed448661dbb30d2e\Fody\Processor.cs:regel 46\r [D:\projects\MyCompany.MessageHandler\src
\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error : Source:\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error : mscorlib\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error : TargetSite:\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
MSBUILD : error : Void CheckInvalidPathChars(System.String, Boolean)\r [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Insta
ller.csproj]
MSBUILD : error :  [D:\projects\MyCompany.MessageHandler\src\MyCompany.Message.Hub.Installer\MyCompany.MessageHub.Installer.csproj]
*** Build failed ***

Sorry should have been posted to general Fody issues!!

Unable to obtain public key for StrongNameKeyPair

I am facing a issue after I integrated methodtimer assembly with my project, the fody threw an exception saying Unable to obtain public key for StrongNameKeyPair. is there anyway I can supply the StrongNameKeyPair ?

Thanks
Steven

Support variables to be added to the time attribute

For example, we have something like this:

[Time("{filename}")
public async Task ReadFileAsync(string filename)
{
    // todo
}

This would only accept parameters inside the method to keep it a bit "simple". Then we can choose to:

  1. Specify a string
  2. Provide a dictionary (but don't want to go here since this will result in a lot of allocations)

If the Time format is not null or empty, we will provide the string.Format method. This way it will only "affect performance" when users actually use this feature.

What do you think?

Expression-bodied member causes System.InvalidProgramException: JIT Compiler encountered an internal limitation.

Describe the issue

When using an expression-bodied member, the IL generated is invalid and causes either one of these two exceptions: ´System.InvalidProgramException: JIT Compiler encountered an internal limitation.or aSystem.InvalidProgramException: Common Language Runtime detected an invalid program.`

  • Fody.4.0.2 as well as Fody v4.2.1
  • MethodTimer.Fody.2.3.2
  • Not sure which .NET Core SDK Rider uses, but it uses the v15 toolset which is part of Visual Studio 2017.
  • CLR v4.0.30319

Note/Use Case: I'm not keen on having MethodTimer on properties, but I wanted to use [assembly: Time] without going through 100s of Methods and adding the [Time] attribute manually. My use case is to accumulate the overall execution time per method, including the number of times it gets called to figure out optimization potential.

Minimal Repro

Create a new, empty solution and add a new console application to it. Add [assembly: Time] to AssemblyInfo.cs

using System.Diagnostics;

namespace ConsoleApplication1
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            var foo = new Foo() {Bar = new Bar()};
            Debug.WriteLine(foo.FooBar); // System.InvalidProgramException
            Debug.WriteLine(foo.FooBar2); // Works
            Debug.WriteLine(foo.FooBar3); // Works
        }
        
        public class Foo
        {
            public bool FooBar => Bar != null && Bar.Foobar;
            public bool FooBar2 => Bar != null;
            
            public bool FooBar3
            {
                get { return Bar != null && Bar.Foobar; }
            }

            public Bar Bar
            {
                get;set;
           
            }
        }

        public class Bar
        {
            public bool Foobar;
        }
    }
}

Use MethodTimer with .NET Framework 3.5

I'm trying to add the Nuget package of Fody.MethodTimer to a project that targets 3.5, and I get an error message.

Impossible to install the package « MethodTimer.Fody 1.14.1.0 ». You are trying to install this package into a project that targets « .NETFramework,Version=v3.5 », but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

Is there any way I could fixe this ?

Thanks

NullReferenceException on stopwatch

image

This happens on an async method that is nested. Going to check if I can reproduce. This code has always worked, just updated to latest version of MethodTimer and it fails now.

Nesting of method timers

Where it is clear that the below content has not read, the issue is likely to be closed with "please read the template". Please don't take offense at this. It is simply a time management decision. When someone raises an issue, without reading the template, then often too much time is spent going back and forth to obtain information that is outlined below.

You should already be a Patron

We are a patron

Is the proposal related to a problem

We have a lot of timings, and are trying to figure out performance measurements. This results in a lot of "nested timings", e.g.:

Method X took '23 ms'
Method Y took '25 ms'
Method Z took '27 ms'

In this case, it's hard to see why Z takes 27, but most time is taken by X.

A proposal would be to have an (optional) scope manager that checks the depth of a method timer. This could result in:

    Method X took '23 ms'
  Method Y took '25 ms'
Method Z took '27 ms'

Describe the solution

This would be an optional feature (disabled by default).

Happy to implement this myself as a PR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.