Vb.net 如何在通用应用程序中读取任意文件夹?

Vb.net 如何在通用应用程序中读取任意文件夹?,vb.net,uwp,windows-10-universal,Vb.net,Uwp,Windows 10 Universal,我正在努力学习编写通用应用程序,我正在尝试重新创建我在WinForms中编写的另一个项目。我需要能够读取任意文件夹中的日志文件,据我所知,我需要获得用户访问该文件夹的权限。然后我应该存储一个访问令牌,以便将来可以重新读取该文件夹。通过四处阅读,我成功地拼凑了以下代码: Friend Async Function GetLogFolder() As Task(Of StorageFolder) Dim myLogFolder As StorageFolder If Applicat

我正在努力学习编写通用应用程序,我正在尝试重新创建我在WinForms中编写的另一个项目。我需要能够读取任意文件夹中的日志文件,据我所知,我需要获得用户访问该文件夹的权限。然后我应该存储一个访问令牌,以便将来可以重新读取该文件夹。通过四处阅读,我成功地拼凑了以下代码:

Friend Async Function GetLogFolder() As Task(Of StorageFolder)
    Dim myLogFolder As StorageFolder
    If ApplicationData.Current.LocalSettings.Values.ContainsKey("LogFolder") Then
        Dim sToken As String = ApplicationData.Current.LocalSettings.Values("LogFolder")
        myLogFolder = StorageApplicationPermissions.FutureAccessList.GetFileAsync(sToken)
    Else
        Dim myFolderPicker As FolderPicker = New FolderPicker
        myFolderPicker.FileTypeFilter.Add("*")
        myLogFolder = Await myFolderPicker.PickSingleFolderAsync

        Dim sToken As String = StorageApplicationPermissions.FutureAccessList.Add(myLogFolder)
        ApplicationData.Current.LocalSettings.Values.Add("LogFolder", sToken)
    End If
    Return myLogFolder
End Function
但它似乎不起作用。在这个阶段,我有一个只包含一个文本块和按钮的表单。单击该按钮将调用一个方法,该方法将解析给定文件夹中的所有*.log文件。它做的第一件事是:

Dim myFolder As StorageFolder = GetLogFolder.Result
当代码运行时,我单击该按钮,会显示一个文件夹浏览器对话框,但随后所有内容都冻结,我必须切换到Visual Studio并单击“停止”。我可能犯了一些愚蠢的错误,但我不知道是什么


任何帮助都将不胜感激。

问题很可能不是由文件访问代码本身引起的,而是由您使用异步API的方式引起的

由于
GetLogFolder
方法返回
StorageFolder
Task
,因此您需要等待结果,而不是使用
result
属性获取结果。原因是
async/await
模式允许您在单独的线程上执行I/O工作,但在完成后将控制返回到UI线程。这里要做的是调用
GetLogFolder
方法,让用户使用
FolderPicker
选择一个文件夹问题就在这里-当控件返回到您的代码时,用户会看到一个文件夹选择器,您可以查询
GetLogFolder
方法返回的
任务
结果
属性。查询
结果
属性会导致UI线程停止并等待
任务
完成以获取结果。不幸的是,当用户选择文件夹时,控件希望返回UI线程以继续执行
GetLogFolder
方法的其余部分,因此出现了死锁
Result
属性停止UI线程以等待
Task
结果,
Task
等待UI线程变为可用。两者都无法继续,因此应用程序完全冻结

解决方案非常简单-使用
async
/
await
关键字。您可以在VB.NET中阅读更多关于它们的信息

在您的情况下,第一步是使按钮的
单击
处理程序方法
异步
,然后用以下代码替换其中的代码:

Dim myFolder As StorageFolder = Await GetLogFolder