0

Here's my example code. It's of no use, but it's short.

I have an array to switch on or off the creation of Exceptions at different parts of my code and two functions. The first (Level 0) is an iterator function to deliver all the data (for instance reading all the files in a directory), and the second one (Level 1) is a function to deliver the data for one specific item (for instance reading and interpreting exactly one file).

Private _errorOnLevel As Boolean() = {False, False}

Private Iterator Function GetAllData() As IEnumerable(Of Integer)
    If _errorOnLevel(0) Then
        Throw New Exception("Error in GetAllData")
    End If

    Yield GetSingleData(1)
    Yield GetSingleData(2)
    Yield GetSingleData(3)
End Function

Private Function GetSingleData(value As Integer) As Integer
    If _errorOnLevel(1) Then
        Throw New Exception("Error in GetSingleData")
    End If

    Return value
End Function

I want to get all the data inside of the constructor of a view model, and because the real code needs a little bit of time to read and process all the data, I want to exceute the code asyncronously so that the window can render itself without waiting for all the data to be read and processed.

Async/Await can't really be used in a constructor of a class (so I read), so I tried a different approach (example code is for a console program):

Public Sub Main()
    Dim t1 As Task = Task.Factory.
    StartNew(Of IEnumerable(Of Integer))(AddressOf GetAllData).
    ContinueWith(
    Sub(t2 As Task(Of IEnumerable(Of Integer)))
        For Each item As Integer In t2.Result
            Console.WriteLine(item)
        Next item
    End Sub)
End Sub

This works as long as there are no errors. But when "activating" my errors, what do I need to do to catch those errors to be able to react to it?

Putting the whole Dim t1 as Task code inside a Try/Catch does nothing.

Adding a task continuation with TaskContinuationOptions.OnlyOnFaulted in the middle or at the end of my task chain does nothing.

Dim t1 As Task = Task.Factory.
    StartNew(Of IEnumerable(Of Integer))(AddressOf GetAllData).
    ContinueWith(
    Sub(t2 As Task(Of IEnumerable(Of Integer)))
        Console.WriteLine("Error in Task 1")
    End Sub, TaskContinuationOptions.OnlyOnFaulted).
    ContinueWith(
    Sub(t3 As Task(Of IEnumerable(Of Integer)))
        For Each item As Integer In t3.Result
            Console.WriteLine(item)
        Next item
    End Sub)

The only solution I found so far is to put a Try/Catch inside the continuation task and returning a possible exception and reacting to this result in another continuation.

Dim t1 As Task = Task.Factory.
    StartNew(Of IEnumerable(Of Integer))(AddressOf GetAllData).
    ContinueWith(Of Exception)(
    Function(t2 As Task(Of IEnumerable(Of Integer))) As Exception
        Try
            For Each item As Integer In t2.Result
                Console.WriteLine(item)
            Next item

            Return Nothing
        Catch ex As Exception
            Return ex
        End Try
    End Function).
    ContinueWith(
    Sub(t3 As Task(Of Exception))
        If t3.Result IsNot Nothing Then
            Console.WriteLine(t3.Result.Message)
        End If
    End Sub)

But is that really the way to go?

3
  • 2
    The code is unreadable. Please clean it up and use async/await. You gain nothing by using 2010-era code. Whatever the problem is will disappear almost immediately. used in a constructor of a class then don't do this in a constructor. A constructor should return a viable object. Sure, you can hide the tasks with Task.Run but the object will be incomplete until later Commented Sep 1 at 12:21
  • Besides, you can't have an async constructor but that doesn't mean it can't call an async Task method and store the returned task in a field, eg MyCrawler(string folder){ _crawlTask=Task.Run(()=>Crawl(folder)); } Commented Sep 1 at 12:23
  • the constructor of a view model that's definitely not the place to load data in MVVM. A ViewModel contains the results of queries, typically triggered by commands (if the MVVM framework supports them) or UI events. Commented Sep 1 at 12:29

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.