mirror of https://github.com/icsharpcode/ILSpy.git
4 changed files with 421 additions and 81 deletions
@ -1,51 +1,254 @@
@@ -1,51 +1,254 @@
|
||||
using System; |
||||
using System.IO; |
||||
using System.Collections.Generic; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Threading.Tasks; |
||||
|
||||
using Microsoft.VisualBasic.CompilerServices; |
||||
|
||||
[StandardModule] |
||||
internal sealed class AsyncProgram |
||||
namespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty |
||||
{ |
||||
[STAThread] |
||||
public static void Main(string[] args) |
||||
public class Async |
||||
{ |
||||
Task task = new Task(ProcessDataAsync); |
||||
task.Start(); |
||||
task.Wait(); |
||||
Console.ReadLine(); |
||||
} |
||||
private int memberField; |
||||
|
||||
public static async void ProcessDataAsync() |
||||
{ |
||||
Task<int> task = HandleFileAsync("C:\\enable1.txt"); |
||||
Console.WriteLine("Please wait, processing"); |
||||
Console.WriteLine("Count: " + await task); |
||||
} |
||||
private static bool True() |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public static async Task<int> HandleFileAsync(string file) |
||||
{ |
||||
Console.WriteLine("HandleFile enter"); |
||||
int num = 0; |
||||
checked |
||||
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() |
||||
{ |
||||
using (StreamReader streamReader = new StreamReader(file)) |
||||
#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() |
||||
{ |
||||
Console.WriteLine("Before"); |
||||
await Task.Delay(TimeSpan.FromSeconds(1.0)); |
||||
Console.WriteLine("After"); |
||||
return true; |
||||
} |
||||
|
||||
public async void TwoAwaitsWithDifferentAwaiterTypes() |
||||
{ |
||||
Console.WriteLine("Before"); |
||||
if (await SimpleBoolTaskMethod()) |
||||
{ |
||||
await Task.Delay(TimeSpan.FromSeconds(1.0)); |
||||
} |
||||
Console.WriteLine("After"); |
||||
} |
||||
|
||||
public async void AwaitInLoopCondition() |
||||
{ |
||||
while (await SimpleBoolTaskMethod()) |
||||
{ |
||||
string text = await streamReader.ReadToEndAsync(); |
||||
num += text.Length; |
||||
int num2 = 0; |
||||
do |
||||
Console.WriteLine("Body"); |
||||
} |
||||
} |
||||
|
||||
public async Task Issue2366a() |
||||
{ |
||||
while (true) |
||||
{ |
||||
try |
||||
{ |
||||
await Task.CompletedTask; |
||||
} |
||||
catch (Exception projectError) |
||||
{ |
||||
if (text.GetHashCode() == 0) |
||||
{ |
||||
num--; |
||||
} |
||||
num2++; |
||||
} while (num2 <= 10000); |
||||
ProjectData.SetProjectError(projectError); |
||||
ProjectData.ClearProjectError(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
Console.WriteLine("HandleFile exit"); |
||||
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; |
||||
} |
||||
|
||||
public async Task AsyncCatch(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"); |
||||
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,48 +1,181 @@
@@ -1,48 +1,181 @@
|
||||
Imports System |
||||
Imports System.IO |
||||
Imports System.Collections.Generic |
||||
Imports System.Threading.Tasks |
||||
Imports System.Runtime.CompilerServices |
||||
|
||||
Module AsyncProgram |
||||
' Sample taken verbatim from https://www.dotnetperls.com/async-vbnet |
||||
Sub Main(args As String()) |
||||
Dim task = New Task(AddressOf ProcessDataAsync) |
||||
' Start and wait for task to end. |
||||
task.Start() |
||||
task.Wait() |
||||
Console.ReadLine() |
||||
End Sub |
||||
|
||||
Async Sub ProcessDataAsync() |
||||
' Create a task Of Integer. |
||||
' ... Use HandleFileAsync method with a large file. |
||||
Dim task As Task(Of Integer) = HandleFileAsync("C:\enable1.txt") |
||||
' This statement runs while HandleFileAsync executes. |
||||
Console.WriteLine("Please wait, processing") |
||||
' Use await to wait for task to complete. |
||||
Dim result As Integer = Await task |
||||
Console.WriteLine("Count: " + result.ToString()) |
||||
End Sub |
||||
|
||||
Async Function HandleFileAsync(ByVal file As String) As Task(Of Integer) |
||||
Console.WriteLine("HandleFile enter") |
||||
|
||||
' Open the file. |
||||
Dim count As Integer = 0 |
||||
Using reader As StreamReader = New StreamReader(file) |
||||
Dim value As String = Await reader.ReadToEndAsync() |
||||
count += value.Length |
||||
|
||||
' Do a slow computation on the file. |
||||
For i = 0 To 10000 Step 1 |
||||
Dim x = value.GetHashCode() |
||||
If x = 0 Then |
||||
count -= 1 |
||||
End If |
||||
|
||||
Next |
||||
End Using |
||||
|
||||
Console.WriteLine("HandleFile exit") |
||||
Return count |
||||
End Function |
||||
End Module |
||||
Namespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty |
||||
Public Class Async |
||||
Private memberField As Integer |
||||
|
||||
Private Shared Function [True]() As Boolean |
||||
Return True |
||||
End Function |
||||
|
||||
Public Async Sub SimpleVoidMethod() |
||||
Console.WriteLine("Before") |
||||
Await Task.Delay(TimeSpan.FromSeconds(1.0)) |
||||
Console.WriteLine("After") |
||||
End Sub |
||||
|
||||
Public Async Sub VoidMethodWithoutAwait() |
||||
Console.WriteLine("No Await") |
||||
End Sub |
||||
|
||||
Public Async Sub EmptyVoidMethod() |
||||
End Sub |
||||
|
||||
Public Async Sub AwaitYield() |
||||
Await Task.Yield() |
||||
End Sub |
||||
|
||||
Public Async Sub AwaitDefaultYieldAwaitable() |
||||
Await CType(Nothing, YieldAwaitable) |
||||
End Sub |
||||
|
||||
Public Async Sub AwaitDefaultHopToThreadPool() |
||||
' unlike YieldAwaitable which implements ICriticalNotifyCompletion, |
||||
' the HopToThreadPoolAwaitable struct only implements |
||||
' INotifyCompletion, so this results in different codegen |
||||
Await CType(Nothing, HopToThreadPoolAwaitable) |
||||
End Sub |
||||
|
||||
Public Async Function SimpleVoidTaskMethod() As Task |
||||
Console.WriteLine("Before") |
||||
Await Task.Delay(TimeSpan.FromSeconds(1.0)) |
||||
Console.WriteLine("After") |
||||
End Function |
||||
|
||||
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