异步和等待,为什么两个返回值

时间:2016-02-14 00:55:19

标签: vb.net async-await

我正试图绕过Async and Await。这很顺利,但有一点我想澄清一下,为什么我的方法中有两个return语句。我真的在寻找对幕后实际发生的事情的解释。

我将在下面发布完整的代码,因为它只有大约80行。我说的是核心方法AllSubfolderFiles,它同时包含Return counterReturn 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被编组回UI线程,但我不相信我的解释。

enter image description here

1 个答案:

答案 0 :(得分:2)

AllSubfolderFiles函数中,您调用Task.Run并传入一个以Return counter返回的匿名函数。 AllSubfolderFiles等待该调用的结果,然后返回Return dirsFraction

因此,在同一个函数中有2个返回值,因为在原始函数中有一个匿名函数。您可以将该函数移动到其自己的命名函数,这将更清楚地表明这里有2个不同的函数。