1

My application is written in VB.net and for reasons beyond my control, I cannot change the technology. I am trying to use AWS S3 buckets to store files. My application in VB will need to show a window which lists files in a bucket and enable the users to download them.

The listing of files in S3 is done using an Async Task using C#

 public async Task<List<string>> listAllContentsAsync()
        {
            List<string> contents = new List<string>();
            client = new AmazonS3Client(bucketRegion);
            ListObjectsV2Request request = new ListObjectsV2Request
            {
                BucketName = bucketName,
                MaxKeys = 20
            };

            ListObjectsV2Response response;
            do
            {
                response = await client.ListObjectsV2Async(request);

                foreach (S3Object entry in response.S3Objects)
                {
                    String contentName = entry.Key.Split('.')[0];
                    contents.Add(contentName);
                }

                request.ContinuationToken = response.NextContinuationToken;
            } while (response.IsTruncated);

            return contents;
        }

I then create a dll for the project in C# and reference it in the VB project. Just for a POC I created a sample VB project which would instantiate an object and call the listAllContentsAsync method to list contents.

I had to change the signature of the Main method because the function I am calling is Async. Here is the updated Main method in VB :

Async Function Main() As Task(Of Task)
    Dim objcsClass = New CallMeFromVB.ClassInCSharpProject()
    Dim inputChar As ConsoleKeyInfo = Console.ReadKey()
    Dim contents As New List(Of String)

    contents = Await objcsClass.listAllContentsAsync()
    For Each content As String In contents
        Console.Write(content & " ")
    Next

End Function

Now, when I try to run my VB project, I get an error saying that there is no Main method in the project. Is there a way I can call an Async method (listAllContentsAsync) from the VB Main method?

s_om
  • 661
  • 2
  • 9
  • 24
  • 1
    did you look at https://stackoverflow.com/questions/9208921/cant-specify-the-async-modifier-on-the-main-method-of-a-console-app? – Dhawalk Jun 02 '20 at 16:56
  • Thank you @Dhawalk, but that solution is for a C# main method calling another C# Async method. I am not able to use the Nito.Asyncx in VB in the way that's described in the question you mentioned above. – s_om Jun 02 '20 at 17:09
  • I was recommending using the same pattern. I haven't tried it – Dhawalk Jun 02 '20 at 17:24
  • 2
    "VB is not an option in the AWS SDK" - huh? Last I knew the AWS SDK was a compiled nuget package; it doesnt matter what flavor of .net it was written in/what flavor of .net it is used in. The SDK works equally well in C# and VB – Caius Jard Jun 02 '20 at 17:46
  • I apologize, I am very new to VB and .Net, I didnt find VB option on the AWS tutorials site and thought, that VB might not be an option – s_om Jun 02 '20 at 18:07
  • 1
    C# and VB.NET are both languages that run on the .NET platform. They can consume assemblies written in one or the other, because it all compiles down to [CIL](https://en.wikipedia.org/wiki/Common_Intermediate_Language). You often only see a C# tutorial because C# is the far more popular language. If you're going to develop in VB.NET, it would be to your benefit to at least learn how to read C# so that you can understand tutorials and documentation. – mason Jun 03 '20 at 13:21

1 Answers1

3

Just turn it syncronous:

Sub Main() 
    Dim objcsClass = New CallMeFromVB.ClassInCSharpProject()
    Dim inputChar As ConsoleKeyInfo = Console.ReadKey()
    Dim contents As New List(Of String)
    contents = objcsClass.listAllContentsAsync().GetAwaiter().GetResult()
    For Each content As String In contents
        Console.Write(content & " ")
    Next

End Sub
Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • I'm not sure this needs to be done through `GetAwaiter`? Since the result is a `Task` I think you could just use `Result` on the task directly. – Craig Jun 03 '20 at 13:57
  • 1
    If it errors, via `.Result` it'll be wrapped in an AggregateException - I didn't want to add another headache for an OP who seemingly isn't so well versed in TAP – Caius Jard Jun 03 '20 at 14:49