Async и Await, почему два возвращаемых значения

Я пытаюсь понять Async and Await. Все идет хорошо, но я хотел бы уточнить одну вещь: почему в моем методе есть два оператора return. Я действительно ищу объяснение тому, что на самом деле происходит за кулисами.

Я опубликую полный код ниже, так как он составляет всего около 80 строк. Я говорю о центральном методе AllSubfolderFiles, в котором есть и Return counter, и Return dirsFraction. Что на самом деле происходит с этими?

По сути, это приложение WinForm, которое перебирает все файлы подпапок, обновляя ProgressBar для каждой итерируемой подпапки.

Imports System.IO

Public Class frmAsyncProgress

    Private Sub frmAsyncProgress_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        barFileProgress.Minimum = 0
        barFileProgress.Maximum = 100
        btnCancel.Enabled = False
    End Sub

    Private Async Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
        If String.IsNullOrWhiteSpace(txtPath.Text) Then
            MessageBox.Show("Provide a location first.", "Location")
            Exit Sub
        End If
        Dim sLocation As String = txtPath.Text.Trim()
        If Not Directory.Exists(sLocation) Then
            MessageBox.Show("Directory doesn't exist.", "Location")
            Exit Sub
        End If

        Dim progressIndicator = New Progress(Of Integer)(AddressOf UpdateProgress)
        btnStart.Enabled = False
        btnCancel.Enabled = True
        lblPercent.Text = "0%"

        Dim allFiles As Integer = Await AllSubfolderFiles(sLocation, progressIndicator)
        Debug.WriteLine(allFiles.ToString())        'the number of subfolders iterated
        btnStart.Enabled = True
        btnCancel.Enabled = False
    End Sub

    Private Async Function AllSubfolderFiles(location As String, progress As IProgress(Of Integer)) As Task(Of Integer)
        Dim dirsTotal As Integer = Directory.GetDirectories(location).Length
        Dim dirsFraction As Integer = Await Task(Of Integer).Run(Function()
                                                                     Dim counter As Integer = 0
                                                                     For Each subDir As String In Directory.GetDirectories(location)
                                                                         SubfolderFiles(subDir)
                                                                         counter += 1
                                                                         If progress IsNot Nothing Then
                                                                             progress.Report(counter * 100 / dirsTotal)
                                                                         End If
                                                                     Next

                                                                     Return counter
                                                                 End Function)
        Return dirsFraction
    End Function

    Private Sub UpdateProgress(value As Integer)
        barFileProgress.Value = value
        lblPercent.Text = (value / 100).ToString("#0.##%")
    End Sub

    Private Sub SubfolderFiles(location As String)
        'source: http://stackoverflow.com/questions/16237291/visual-basic-2010-continue-on-error-unauthorizedaccessexception#answer-16237749

        Dim paths = New Queue(Of String)()
        Dim fileNames = New List(Of String)()

        paths.Enqueue(location)

        While paths.Count > 0
            Dim sDir = paths.Dequeue()

            Try
                Dim files = Directory.GetFiles(sDir)
                For Each file As String In Directory.GetFiles(sDir)
                    fileNames.Add(file)
                Next

                For Each subDir As String In Directory.GetDirectories(sDir)
                    paths.Enqueue(subDir)
                Next
            Catch ex As UnauthorizedAccessException
                ' log the exception or ignore it
                Debug.WriteLine("Directory {0}  could not be accessed!", sDir)
            Catch ex As Exception
                ' log the exception or ...
                Throw
            End Try
        End While
        'could return fileNames collection
    End Sub
End Class

Моя оценка такова, что counter возвращается, а затем направляется обратно в поток пользовательского интерфейса как dirsFraction, но меня не убеждают мои попытки объяснения.

введите здесь описание изображения


person Andy G    schedule 14.02.2016    source источник


Ответы (1)


Внутри вашей функции AllSubfolderFiles вы вызываете Task.Run и передаете анонимную функцию, которая возвращается с Return counter. AllSubfolderFiles ожидает результата этого вызова, а затем возвращается с Return dirsFraction.

Итак, у вас есть 2 возврата в одной и той же функции, потому что у вас есть анонимная функция внутри исходной функции. Вы можете переместить эту функцию в функцию с ее собственным именем, что прояснит, что здесь есть 2 разные функции.

person i3arnon    schedule 14.02.2016
comment
Большое спасибо, это имеет смысл (я был почти там ;)). - person Andy G; 14.02.2016