mirror of https://github.com/icsharpcode/ILSpy.git
5 changed files with 656 additions and 132 deletions
@ -1 +1,3 @@ |
|||||||
*.dll |
/*.dll |
||||||
|
/*.exe |
||||||
|
/*.pdb |
@ -1,45 +1,255 @@ |
|||||||
using System; |
using System; |
||||||
using System.IO; |
using System.Collections.Generic; |
||||||
|
using System.Runtime.CompilerServices; |
||||||
using System.Threading.Tasks; |
using System.Threading.Tasks; |
||||||
|
|
||||||
namespace EquivalentCSharpConsoleApp |
using Microsoft.VisualBasic.CompilerServices; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty |
||||||
{ |
{ |
||||||
static class Program |
public class Async |
||||||
{ |
{ |
||||||
public static void Main(string[] args) |
private int memberField; |
||||||
|
|
||||||
|
private static bool True() |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public async void SimpleVoidMethod() |
||||||
|
{ |
||||||
|
Console.WriteLine("Before"); |
||||||
|
await Task.Delay(TimeSpan.FromSeconds(1.0)); |
||||||
|
Console.WriteLine("After"); |
||||||
|
} |
||||||
|
|
||||||
|
public async void VoidMethodWithoutAwait() |
||||||
|
{ |
||||||
|
Console.WriteLine("No Await"); |
||||||
|
} |
||||||
|
|
||||||
|
public async void EmptyVoidMethod() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public async void AwaitYield() |
||||||
|
{ |
||||||
|
await Task.Yield(); |
||||||
|
} |
||||||
|
|
||||||
|
public async void AwaitDefaultYieldAwaitable() |
||||||
|
{ |
||||||
|
#if LEGACY_VBC || (OPTIMIZE && !ROSLYN4)
|
||||||
|
YieldAwaitable yieldAwaitable = default(YieldAwaitable); |
||||||
|
YieldAwaitable yieldAwaitable2 = yieldAwaitable; |
||||||
|
await yieldAwaitable2; |
||||||
|
#else
|
||||||
|
await default(YieldAwaitable); |
||||||
|
#endif
|
||||||
|
} |
||||||
|
|
||||||
|
public async void AwaitDefaultHopToThreadPool() |
||||||
|
{ |
||||||
|
#if LEGACY_VBC || (OPTIMIZE && !ROSLYN4)
|
||||||
|
HopToThreadPoolAwaitable hopToThreadPoolAwaitable = default(HopToThreadPoolAwaitable); |
||||||
|
HopToThreadPoolAwaitable hopToThreadPoolAwaitable2 = hopToThreadPoolAwaitable; |
||||||
|
await hopToThreadPoolAwaitable2; |
||||||
|
#else
|
||||||
|
await default(HopToThreadPoolAwaitable); |
||||||
|
#endif
|
||||||
|
} |
||||||
|
|
||||||
|
public async Task SimpleVoidTaskMethod() |
||||||
|
{ |
||||||
|
Console.WriteLine("Before"); |
||||||
|
await Task.Delay(TimeSpan.FromSeconds(1.0)); |
||||||
|
Console.WriteLine("After"); |
||||||
|
} |
||||||
|
|
||||||
|
public async Task TaskMethodWithoutAwait() |
||||||
|
{ |
||||||
|
Console.WriteLine("No Await"); |
||||||
|
} |
||||||
|
|
||||||
|
public async Task CapturingThis() |
||||||
|
{ |
||||||
|
await Task.Delay(memberField); |
||||||
|
} |
||||||
|
|
||||||
|
public async Task CapturingThisWithoutAwait() |
||||||
|
{ |
||||||
|
Console.WriteLine(memberField); |
||||||
|
} |
||||||
|
|
||||||
|
public async Task<bool> SimpleBoolTaskMethod() |
||||||
{ |
{ |
||||||
var task = new Task(ProcessDataAsync); |
Console.WriteLine("Before"); |
||||||
task.Start(); |
await Task.Delay(TimeSpan.FromSeconds(1.0)); |
||||||
task.Wait(); |
Console.WriteLine("After"); |
||||||
Console.ReadLine(); |
return true; |
||||||
} |
} |
||||||
|
|
||||||
public async static void ProcessDataAsync() |
public async void TwoAwaitsWithDifferentAwaiterTypes() |
||||||
{ |
{ |
||||||
Task<int> task = HandleFileAsync("C:\\enable1.txt"); |
Console.WriteLine("Before"); |
||||||
Console.WriteLine("Please wait, processing"); |
if (await SimpleBoolTaskMethod()) |
||||||
int result = await task; |
{ |
||||||
Console.WriteLine("Count: " + result.ToString()); |
await Task.Delay(TimeSpan.FromSeconds(1.0)); |
||||||
|
} |
||||||
|
Console.WriteLine("After"); |
||||||
|
} |
||||||
|
|
||||||
|
public async void AwaitInLoopCondition() |
||||||
|
{ |
||||||
|
while (await SimpleBoolTaskMethod()) |
||||||
|
{ |
||||||
|
Console.WriteLine("Body"); |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
public async static Task<int> HandleFileAsync(string file) |
public async Task Issue2366a() |
||||||
{ |
{ |
||||||
Console.WriteLine("HandleFile enter"); |
while (true) |
||||||
int count = 0; |
|
||||||
using (StreamReader reader = new StreamReader(file)) |
|
||||||
{ |
{ |
||||||
string value = await reader.ReadToEndAsync(); |
try |
||||||
count += value.Length; |
|
||||||
for (var i = 0; i <= 10000; i += 1) |
|
||||||
{ |
{ |
||||||
var x = value.GetHashCode(); |
await Task.CompletedTask; |
||||||
if (x == 0) |
|
||||||
count -= 1; |
|
||||||
} |
} |
||||||
|
catch (Exception projectError) |
||||||
|
{ |
||||||
|
ProjectData.SetProjectError(projectError); |
||||||
|
ProjectData.ClearProjectError(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static async Task<int> GetIntegerSumAsync(IEnumerable<int> items) |
||||||
|
{ |
||||||
|
await Task.Delay(100); |
||||||
|
int num = 0; |
||||||
|
foreach (int item in items) |
||||||
|
{ |
||||||
|
num = checked(num + item); |
||||||
} |
} |
||||||
|
return num; |
||||||
|
} |
||||||
|
|
||||||
Console.WriteLine("HandleFile exit"); |
public async Task AsyncCatch(bool b, Task<int> task1, Task<int> task2) |
||||||
return count; |
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
Console.WriteLine("Start try"); |
||||||
|
await task1; |
||||||
|
Console.WriteLine("End try"); |
||||||
|
} |
||||||
|
catch (Exception projectError) |
||||||
|
{ |
||||||
|
ProjectData.SetProjectError(projectError); |
||||||
|
Console.WriteLine("No await"); |
||||||
|
ProjectData.ClearProjectError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public async Task AsyncCatchThrow(bool b, Task<int> task1, Task<int> task2) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
Console.WriteLine("Start try"); |
||||||
|
await task1; |
||||||
|
Console.WriteLine("End try"); |
||||||
|
} |
||||||
|
catch (Exception projectError) |
||||||
|
{ |
||||||
|
ProjectData.SetProjectError(projectError); |
||||||
|
Console.WriteLine("No await"); |
||||||
|
throw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public async Task AsyncFinally(bool b, Task<int> task1, Task<int> task2) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
Console.WriteLine("Start try"); |
||||||
|
await task1; |
||||||
|
Console.WriteLine("End try"); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
Console.WriteLine("No await"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static async Task AlwaysThrow() |
||||||
|
{ |
||||||
|
throw new Exception(); |
||||||
|
} |
||||||
|
|
||||||
|
public static async Task InfiniteLoop() |
||||||
|
{ |
||||||
|
while (true) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static async Task InfiniteLoopWithAwait() |
||||||
|
{ |
||||||
|
while (true) |
||||||
|
{ |
||||||
|
await Task.Delay(10); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public async Task AsyncWithLocalVar() |
||||||
|
{ |
||||||
|
object objectValue = RuntimeHelpers.GetObjectValue(new object()); |
||||||
|
await UseObj(RuntimeHelpers.GetObjectValue(objectValue)); |
||||||
|
await UseObj(RuntimeHelpers.GetObjectValue(objectValue)); |
||||||
|
} |
||||||
|
|
||||||
|
public static async Task UseObj(object a) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public struct AsyncInStruct |
||||||
|
{ |
||||||
|
private int i; |
||||||
|
|
||||||
|
public async Task<int> Test(AsyncInStruct xx) |
||||||
|
{ |
||||||
|
checked |
||||||
|
{ |
||||||
|
xx.i++; |
||||||
|
i++; |
||||||
|
await Task.Yield(); |
||||||
|
return i + xx.i; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public struct HopToThreadPoolAwaitable : INotifyCompletion |
||||||
|
{ |
||||||
|
public bool IsCompleted { get; set; } |
||||||
|
|
||||||
|
public HopToThreadPoolAwaitable GetAwaiter() |
||||||
|
{ |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCompleted(Action continuation) |
||||||
|
{ |
||||||
|
Task.Run(continuation); |
||||||
|
} |
||||||
|
|
||||||
|
void INotifyCompletion.OnCompleted(Action continuation) |
||||||
|
{ |
||||||
|
//ILSpy generated this explicit interface implementation from .override directive in OnCompleted
|
||||||
|
this.OnCompleted(continuation); |
||||||
|
} |
||||||
|
|
||||||
|
public void GetResult() |
||||||
|
{ |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,47 +1,181 @@ |
|||||||
Imports System |
Imports System |
||||||
Imports System.IO |
Imports System.Collections.Generic |
||||||
|
Imports System.Threading.Tasks |
||||||
Module Program |
Imports System.Runtime.CompilerServices |
||||||
' Sample taken verbatim from https://www.dotnetperls.com/async-vbnet |
|
||||||
Sub Main(args As String()) |
Namespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty |
||||||
Dim task = New Task(AddressOf ProcessDataAsync) |
Public Class Async |
||||||
' Start and wait for task to end. |
Private memberField As Integer |
||||||
task.Start() |
|
||||||
task.Wait() |
Private Shared Function [True]() As Boolean |
||||||
Console.ReadLine() |
Return True |
||||||
End Sub |
End Function |
||||||
|
|
||||||
Async Sub ProcessDataAsync() |
Public Async Sub SimpleVoidMethod() |
||||||
' Create a task Of Integer. |
Console.WriteLine("Before") |
||||||
' ... Use HandleFileAsync method with a large file. |
Await Task.Delay(TimeSpan.FromSeconds(1.0)) |
||||||
Dim task As Task(Of Integer) = HandleFileAsync("C:\enable1.txt") |
Console.WriteLine("After") |
||||||
' This statement runs while HandleFileAsync executes. |
End Sub |
||||||
Console.WriteLine("Please wait, processing") |
|
||||||
' Use await to wait for task to complete. |
Public Async Sub VoidMethodWithoutAwait() |
||||||
Dim result As Integer = Await task |
Console.WriteLine("No Await") |
||||||
Console.WriteLine("Count: " + result.ToString()) |
End Sub |
||||||
End Sub |
|
||||||
|
Public Async Sub EmptyVoidMethod() |
||||||
Async Function HandleFileAsync(ByVal file As String) As Task(Of Integer) |
End Sub |
||||||
Console.WriteLine("HandleFile enter") |
|
||||||
|
Public Async Sub AwaitYield() |
||||||
' Open the file. |
Await Task.Yield() |
||||||
Dim count As Integer = 0 |
End Sub |
||||||
Using reader As StreamReader = New StreamReader(file) |
|
||||||
Dim value As String = Await reader.ReadToEndAsync() |
Public Async Sub AwaitDefaultYieldAwaitable() |
||||||
count += value.Length |
Await CType(Nothing, YieldAwaitable) |
||||||
|
End Sub |
||||||
' Do a slow computation on the file. |
|
||||||
For i = 0 To 10000 Step 1 |
Public Async Sub AwaitDefaultHopToThreadPool() |
||||||
Dim x = value.GetHashCode() |
' unlike YieldAwaitable which implements ICriticalNotifyCompletion, |
||||||
If x = 0 Then |
' the HopToThreadPoolAwaitable struct only implements |
||||||
count -= 1 |
' INotifyCompletion, so this results in different codegen |
||||||
End If |
Await CType(Nothing, HopToThreadPoolAwaitable) |
||||||
|
End Sub |
||||||
Next |
|
||||||
End Using |
Public Async Function SimpleVoidTaskMethod() As Task |
||||||
|
Console.WriteLine("Before") |
||||||
Console.WriteLine("HandleFile exit") |
Await Task.Delay(TimeSpan.FromSeconds(1.0)) |
||||||
Return count |
Console.WriteLine("After") |
||||||
End Function |
End Function |
||||||
End Module |
|
||||||
|
Public Async Function TaskMethodWithoutAwait() As Task |
||||||
|
Console.WriteLine("No Await") |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Function CapturingThis() As Task |
||||||
|
Await Task.Delay(memberField) |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Function CapturingThisWithoutAwait() As Task |
||||||
|
Console.WriteLine(memberField) |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Function SimpleBoolTaskMethod() As Task(Of Boolean) |
||||||
|
Console.WriteLine("Before") |
||||||
|
Await Task.Delay(TimeSpan.FromSeconds(1.0)) |
||||||
|
Console.WriteLine("After") |
||||||
|
Return True |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Sub TwoAwaitsWithDifferentAwaiterTypes() |
||||||
|
Console.WriteLine("Before") |
||||||
|
If Await SimpleBoolTaskMethod() Then |
||||||
|
Await Task.Delay(TimeSpan.FromSeconds(1.0)) |
||||||
|
End If |
||||||
|
Console.WriteLine("After") |
||||||
|
End Sub |
||||||
|
|
||||||
|
Public Async Sub AwaitInLoopCondition() |
||||||
|
While Await SimpleBoolTaskMethod() |
||||||
|
Console.WriteLine("Body") |
||||||
|
End While |
||||||
|
End Sub |
||||||
|
|
||||||
|
Public Async Function Issue2366a() As Task |
||||||
|
While True |
||||||
|
Try |
||||||
|
Await Task.CompletedTask |
||||||
|
Catch |
||||||
|
End Try |
||||||
|
End While |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Shared Async Function GetIntegerSumAsync(ByVal items As IEnumerable(Of Integer)) As Task(Of Integer) |
||||||
|
Await Task.Delay(100) |
||||||
|
Dim num = 0 |
||||||
|
For Each item In items |
||||||
|
num += item |
||||||
|
Next |
||||||
|
Return num |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Function AsyncCatch(ByVal b As Boolean, ByVal task1 As Task(Of Integer), ByVal task2 As Task(Of Integer)) As Task |
||||||
|
Try |
||||||
|
Console.WriteLine("Start try") |
||||||
|
Await task1 |
||||||
|
Console.WriteLine("End try") |
||||||
|
Catch ex As Exception |
||||||
|
Console.WriteLine("No await") |
||||||
|
End Try |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Function AsyncCatchThrow(ByVal b As Boolean, ByVal task1 As Task(Of Integer), ByVal task2 As Task(Of Integer)) As Task |
||||||
|
Try |
||||||
|
Console.WriteLine("Start try") |
||||||
|
Await task1 |
||||||
|
Console.WriteLine("End try") |
||||||
|
Catch ex As Exception |
||||||
|
Console.WriteLine("No await") |
||||||
|
Throw |
||||||
|
End Try |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Function AsyncFinally(ByVal b As Boolean, ByVal task1 As Task(Of Integer), ByVal task2 As Task(Of Integer)) As Task |
||||||
|
Try |
||||||
|
Console.WriteLine("Start try") |
||||||
|
Await task1 |
||||||
|
Console.WriteLine("End try") |
||||||
|
Finally |
||||||
|
Console.WriteLine("No await") |
||||||
|
End Try |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Shared Async Function AlwaysThrow() As Task |
||||||
|
Throw New Exception |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Shared Async Function InfiniteLoop() As Task |
||||||
|
While True |
||||||
|
End While |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Shared Async Function InfiniteLoopWithAwait() As Task |
||||||
|
While True |
||||||
|
Await Task.Delay(10) |
||||||
|
End While |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Async Function AsyncWithLocalVar() As Task |
||||||
|
Dim a As Object = New Object() |
||||||
|
Await UseObj(a) |
||||||
|
Await UseObj(a) |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Shared Async Function UseObj(ByVal a As Object) As Task |
||||||
|
End Function |
||||||
|
End Class |
||||||
|
|
||||||
|
Public Structure AsyncInStruct |
||||||
|
Private i As Integer |
||||||
|
|
||||||
|
Public Async Function Test(ByVal xx As AsyncInStruct) As Task(Of Integer) |
||||||
|
xx.i += 1 |
||||||
|
i += 1 |
||||||
|
Await Task.Yield() |
||||||
|
Return i + xx.i |
||||||
|
End Function |
||||||
|
End Structure |
||||||
|
|
||||||
|
Public Structure HopToThreadPoolAwaitable |
||||||
|
Implements INotifyCompletion |
||||||
|
Public Property IsCompleted As Boolean |
||||||
|
|
||||||
|
Public Function GetAwaiter() As HopToThreadPoolAwaitable |
||||||
|
Return Me |
||||||
|
End Function |
||||||
|
|
||||||
|
Public Sub OnCompleted(ByVal continuation As Action) Implements INotifyCompletion.OnCompleted |
||||||
|
Task.Run(continuation) |
||||||
|
End Sub |
||||||
|
|
||||||
|
Public Sub GetResult() |
||||||
|
End Sub |
||||||
|
End Structure |
||||||
|
End Namespace |
||||||
|
Loading…
Reference in new issue