I have my library with one file that contains:
public class SomeClassWithAwait
{
public async Task<int> MethodAsync()
{
return await Task.Run(() => 1 + 1);
}
}
I turn on the feature "Show compiler-generated Code".
I see changes in "Assembly Explorer", for example - state machine for await. But I cannot see changes in the file. I see only async\await as before when I turn on feature from step 2.
What I tried: close\open file, close\open dotPeek, rebuild library in release\debug mode.
Version dotPeek: 2020.2.2 build on 2020-09-09 (latest for today).
Any ideas?
UPDATED
About "Use sources from symbol files when available" feature:
Still doesn't work for me, I got this:
public async Task<int> MethodAsync()
{
int num = await Task.Run<int>((Func<int>) (() => 2));
return num;
}
So, I still have async/await.
Uncheck "Use sources from symbol files when available". Then close the window with the code and reopen it.
Try to open the decompiled source:
Right click on a class -> Decompiled Sources
dotPeek will show the await/async state machine instead of the "async/await" statements.
dotPeek Screenshot
See also the official documentation: https://www.jetbrains.com/help/decompiler/Navigation_and_Search__Navigate_from_Here__Decompiled_Code.html
Related
I am not seeing the code analysis rule csharp_prefer_simple_using_statement aka "Use simple 'using' statement (IDE0063)" produce output when expected. I added some dummy code to a method in my project, like so:
using (var file = Image.FromFile(userName))
{
System.Diagnostics.Debug.Assert(file != null);
}
My .sln-style Solution in VS 2022 includes several .csproj-style Projects (i.e. the "old way"). I have a .editorconfig file in the same folder as my .sln, and a variety of other built-in .NET analyzers and Roslynator analyzers work fine.
In the .editorconfig I have csharp_prefer_simple_using_statement = true:warning, and I
also added dotnet_diagnostic.IDE0063.severity = warning for good measure. I have double-checked that neither are duplicated elsewhere in the config, and there are no other .editorconfig files anywhere in the solution/project folders.
Even though I know it's supposed to be superseded by the .editorconfig file, I found the same setting in VS Options and enabled it there too:
And I also opened the project file (C# 10 / .NET 6 latest, btw), and set <AnalysisLevel>latest-recommended</AnalysisLevel>.
I have cleaned the build, restarted VS, and rebuilt, and I still see nothing in the Output, Error List, or in the editor indicating that it suggests simplifying the using statement. Again, I have many other code analysis rules that product output both live in the editor and in the build output & errors list.
Where am I going wrong, please?
EDIT: #Guru Stron's question tickled my spidey sense, and I discovered that while the first method here does not produce IDE0063, the latter does. Why?
public Stream GenerateReport()
{
using (var reportContext = new ReportRenderContext(this.ReportTemplate))
{
reportContext.Render();
}
return this.FileStream;
}
public static int GetAreaOfImage(string fileName)
{
using (var image = Image.FromFile(fileName))
{
return image.Size.Width * image.Size.Height;
}
}
using declaration works based on scope, resource will be disposed at the end of the scope, so the next one:
public Stream GenerateReport()
{
using (var reportContext = new ReportRenderContext(this.ReportTemplate))
{
reportContext.Render();
}
return this.FileStream;
}
Is not analogous to:
public Stream GenerateReport()
{
using var reportContext = new ReportRenderContext(this.ReportTemplate);
reportContext.Render();
return this.FileStream;
}
The latter one is analogous to:
public Stream GenerateReport()
{
using (var reportContext = new ReportRenderContext(this.ReportTemplate))
{
reportContext.Render();
return this.FileStream;
}
}
Which can have difference in some cases, so due to this compiler will not produce the warning (compiler is very smart and very dumb at the same moment, it does not "really" know what this.FileStream does. For example it can access the same resource as ReportRenderContext (like some file in non-shareable fashion) and disposing after return this.FileStream will introduce runtime error. Or this.FileStream can be just a relatively long operation and one of the main purposes of Dispose is to free resources as soon as they are not needed. There is "reverse" example when the 2nd snippet can fix a "bug" - in async context).
I am trying to see what goes on in the IAsyncStateMachine at runtime ,and i desperately need to see what variables it has and what it calls.I know you can see the code with the ILSpy ...but i need to debug it.
Is there any method?
I need to see what goes on inside the IAsyncStateMachine MoveNext method !
public sealed partial class MethodBuilder<T> : Errand.MethodBuilder {
public static new MethodBuilder<T> Create() => new MethodBuilder<T>();
public new void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine {
this.myStateMachine = stateMachine;
this.Task = new Task<T>(this);
stateMachine.MoveNext(); //i have to see the properties of stateMachine and inside this method !!!!!
}
public new void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine machine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine {
}
public void SetResult(T result) {
this.Task.isCompleted = true;
this.Task.result = result;
}
public new void SetStateMachine(IAsyncStateMachine stateMachine) => base.SetStateMachine(stateMachine);
public new void SetException(Exception ex) => base.SetException(ex);
}
From MSDN How to: Debug .NET Framework Source.
To enable .NET Framework source debugging
On the Tools menu, click Options.
In the Options dialog box, click the Debugging category.
In the General box, set Enable .NET Framework source stepping.
If you had Just My Code enabled, a warning dialog box tells you that
Just My Code is now disabled. Click OK.
If you did not have a symbol cache location set, another warning
dialog box tells you that a default symbol cache location is now
set. Click OK.
Under the Debugging category, click Symbols.
If you want to change the symbols cache location:
Open the Debugging node in the box on the left.
Under the Debugging node, click Symbols.
Edit the location in Cache symbols from symbol servers to this
directory or click Browse to choose a location.
If you want to download symbols immediately, click Load Symbols
using above locations.
This button is not available in design mode.
If you do not choose to download symbols now, symbols will be
downloaded automatically the next time that you start the debugging
your program.
Click OK to close the Options dialog box.
perhaps you can use debugger.launch
once the debugger launch visual studio will prompt for vs version selection
internal class Program
{
public static void Main(string[] args)
{
System.Diagnostics.Debugger.Launch();
Console.WriteLine("crap");
}
}
I am unable to view the debug information when using a Task of Tuple. E.G. When a breakpoint his hit, I cannot view any variables on hover, in the local window, or in the watch window.
The repro is just to create a new WPF app, add System.ValueTuple, add this code to MainWindow.xaml.cs, and then set breakpoints at both lines with "return".
using System.Threading.Tasks;
using System.Windows;
namespace WpfApp2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var task1 = TaskWithLocalDebugInfo();
var task2 = TaskWithoutLocalDebugInfo();
}
private async Task<bool> TaskWithLocalDebugInfo()
{
var viewableInLocalWindowAndHover = true;
return viewableInLocalWindowAndHover;
}
private async Task<(bool, bool)> TaskWithoutLocalDebugInfo()
{
var notViewableInLocalWindowAndHover = true;
return (notViewableInLocalWindowAndHover, notViewableInLocalWindowAndHover);
}
}
}
Edit: If I add the un-viewable local variable to watch, I get: error CS8182: Predefined type 'ValueTuple`2' must be a struct.
It's a bug in the current version of Visual Studio 2017. It has been fixed and will be out in the next quarterly release.
See the GitHub issue and the comment from the MS employee saying it's fixed.
In the meantime, from the GitHub comment on Apr 13, 2017:
i can confirm that the bug repros with ValueTuple 4.3.0, but not with 4.3.0-preview1-24530-04.
You can install the "preview" version via the NuGet Package Manager/Manage NuGet Packages for Solution interface. Just select 4.3.0-preview1-24530-04 from the "Version:" dropdown and click "Install".
One hopes that, after the next update for Visual Studio, using the "preview" version of the package won't be necessary. As noted by the previously mentioned comment, it's not clear why using the "preview" version of the package avoids triggering the bug. But obviously it's preferable to be able to use the latest "stable" version of the package if one can; who knows what changes happened since the "preview" version that would lead to some other hard-to-diagnose bug, in the debugger or otherwise.
After seeing the error in watch window, I remembered that there is a new ValueTask in C# 7. So I added package system.threading.tasks.extensions and changed the broken method to use ValueTask instead of Task
private static async ValueTask<(bool, bool)> TaskWithoutLocalDebugInfo()
{
var notViewableInLocalWindowAndHover = true;
return (notViewableInLocalWindowAndHover, notViewableInLocalWindowAndHover);
}
I can now see the debug information.
I was under the impression Mono's compiler was usable in Microsoft.NET
edit: updated blog posting here that I originally missed that explains some of it (is consistent with Justin's answers)
I created a simple class to try to use it
[TestFixture]
class Class1
{
[Test]
public void EXPR()
{
Evaluator.Run("using System;");
int sum = (int)Evaluator.Evaluate("1+2");
}
}
And a project in Visual Studio 2010 that references C:\Program Files (x86)\Mono-2.10.1\lib\mono\4.0\Mono.CSharp.dll.
However when I try to run this task I get the following exception, thrown at the Evaluator.Run call:
System.TypeInitializationException was unhandled by user code
Message=The type initializer for 'Mono.CSharp.Evaluator' threw an exception.
Source=Mono.CSharp
TypeName=Mono.CSharp.Evaluator
StackTrace:
at Mono.CSharp.Evaluator.Run(String statement)
at Experiments.Class1.EXPR() in W:\Experiments\Class1.cs:line 16
InnerException: System.TypeLoadException
Message=Method 'Mono.CSharp.Location.ToString()' is security transparent, but is a member of a security critical type.
Source=Mono.CSharp
TypeName=Mono.CSharp.Location.ToString()
StackTrace:
at Mono.CSharp.Evaluator..cctor()
InnerException:
A google confirms one other person asking this question but no answer. I tried to start reading the microsoft article on security transparent code but got confused quite quickly. Would someone be able to suggest a quick workaround to allow me to use this? And possibly summarise the security implications, if any, to me (in the context of my situation - in the future I hope to package it with a thick client application, to be used both internally and by end-users)
It has worked under .NET since April of last year.
Small point but I notice you are missing a semi-colon in your expression for sum.
int sum = (int)Evaluator.Evaluate("1+2;");
I only have Mono 2.11 (from git) at the moment and they have changed to using a multi-instance version of the compiler instead of the static version. So, my code looks a little different:
using System;
using Mono.CSharp;
namespace REPLtest
{
class MainClass
{
public static void Main (string[] args)
{
var r = new Report (new ConsoleReportPrinter ());
var cmd = new CommandLineParser (r);
var settings = cmd.ParseArguments (args);
if (settings == null || r.Errors > 0)
Environment.Exit (1);
var evaluator = new Evaluator (settings, r);
evaluator.Run("using System;");
int sum = (int) evaluator.Evaluate("1+2;");
Console.WriteLine ("The sum of 1 + 2 is {0}", sum);
}
}
}
EDIT: I guess I should confirm that I did in fact successfully execute this on .NET 4 (using Visual C# Express 2010 on Windows XP)
EDIT AGAIN: If you have Visual Studio, you can download the latest version of Mono.CSharp and compile it yourself. There is a .sln (solution file) included with the source so you can build it on Windows without Mono. The resulting assembly would run the code above. Miguel has a post explaining the new Mono.CSharp here.
FINAL EDIT: I uploaded the compiled Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.
It looks like this is a bug in Mono.
.NET 4 abandoned Code Access Security but kept the concept of Security Transparent Code. In a nutshell, low-level code that does stuff, like call unmanaged code, must be "security critical". Application level code is marked "transparent". "Transparent" code cannot call into "security critical" code.
It sounds like Mono.CSharp.Location.ToString() needs to be marked with the [SecuritySafeCritical] attribute if you want the Mono 2.10 code to work with .NET 4. Maybe even better would be marking all of Mono.CSharp as SecuritySafeCritical.
http://msdn.microsoft.com/en-us/library/system.security.securitycriticalattribute.aspx
PS. Sorry to have multiple answers for one question. After I realized that 2.11 would work, I became more curious about what the error with 2.10 meant. I cannot really combine this answer with the others.
I decided I should have kept the code more like the question but I did not want to overwrite my previous answer:
The code below works with version 2.11 of Mono.CSharp (available here including a solution file for building with Visual Studio/.NET). It was tested with .NET 4 on Windows XP. I do not have access to Mono 2.10 at the moment.
[TestFixture]
class Class1
{
private Evaluator evaluator;
public Class1()
{
var report = new Report(new ConsoleReportPrinter());
evaluator = new Evaluator(new CompilerSettings(), report);
}
[Test]
public void EXPR()
{
evaluator.Run("using System;");
int sum = (int)evaluator.Evaluate("1+2;");
}
}
EDIT: I uploaded the Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.
So I was trying to run some simple code with Code Contracts (that I haven't used for some time)
static void Main(string[] args)
{
double res = sqrt(-5);
}
static double sqrt(int a)
{
Contract.Requires(a >= 0, "a must be >= 0!");
return Math.Sqrt(a);
}
But it doesn't seem to do anything at all when I run it. From what I recall from some months ago, it should throw up an error about a being less than 0.
I reinstalled the Academic version from the Code Contracts site just to be safe and this still doesn't seem to be working. What are the steps needed to put Code Contracts to work?
EDIT: Resharper is telling me on Contract.Requires(a >= 0); that the method is being skipped, as it is either "conditional or a partial method without implementation".
Thanks
You should check this web page: link text
You should go to the project properties, Code Contracts tab and click the Runtime checkboxes.