如何读取通用应用程序中的任意文件夹?
How to read an arbitrary folder in a Universal app?
我正在尝试学习编写通用应用程序,我开始尝试重新创建我在 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
但是好像不行。在此阶段,我有一个仅包含 TextBlock 和 Button 的表单。单击 Button 将调用一个方法,该方法将解析给定文件夹中的所有 *.log 文件。它做的第一件事是:
Dim myFolder As StorageFolder = GetLogFolder.Result
当代码运行时,我单击按钮,显示了一个文件夹浏览器对话框,但随后一切都冻结了,我必须切换到 Visual Studio 并单击停止。我可能犯了一些愚蠢的错误,但我不知道它是什么。
如有任何帮助,我们将不胜感激。
问题很可能不是文件访问代码本身引起的,而是你使用异步的方式引起的API。
因为 GetLogFolder
方法 return 是 StorageFolder
的 Task
,您将需要等待结果,而不是使用 Result
属性。原因是 async/await
模式允许您在单独的线程上执行 I/O 工作,但 return 控制权在完成后返回 UI 线程。您在这里所做的是调用 GetLogFolder
方法,在该方法中您让用户使用 FolderPicker
选择文件夹。 这就是问题所在 - 用户看到一个文件夹选择器,而控件 return 进入您的代码并且您查询 Result
属性 Task
return 由 GetLogFolder
方法编辑。查询 Result
属性 导致 UI 线程停止并等待 Task
完成以获取结果。不幸的是,当用户选择文件夹时,控件想要 return 到 UI 线程以继续执行 GetLogFolder
方法的其余部分,我们有一个 死锁 。 Result
属性 停止了 UI 线程等待 Task
结果,Task
等待 UI 线程可用。两者都无法继续,因此应用程序完全冻结。
解决方案非常简单 - 使用 async
/ await
关键字。您可以在 VB.NET here with a clear example.
中阅读更多关于它们的信息
在您的情况下,第一步是创建按钮的 Click
处理程序方法 async
,然后将其中的代码替换为以下内容:
Dim myFolder As StorageFolder = Await GetLogFolder
我正在尝试学习编写通用应用程序,我开始尝试重新创建我在 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
但是好像不行。在此阶段,我有一个仅包含 TextBlock 和 Button 的表单。单击 Button 将调用一个方法,该方法将解析给定文件夹中的所有 *.log 文件。它做的第一件事是:
Dim myFolder As StorageFolder = GetLogFolder.Result
当代码运行时,我单击按钮,显示了一个文件夹浏览器对话框,但随后一切都冻结了,我必须切换到 Visual Studio 并单击停止。我可能犯了一些愚蠢的错误,但我不知道它是什么。
如有任何帮助,我们将不胜感激。
问题很可能不是文件访问代码本身引起的,而是你使用异步的方式引起的API。
因为 GetLogFolder
方法 return 是 StorageFolder
的 Task
,您将需要等待结果,而不是使用 Result
属性。原因是 async/await
模式允许您在单独的线程上执行 I/O 工作,但 return 控制权在完成后返回 UI 线程。您在这里所做的是调用 GetLogFolder
方法,在该方法中您让用户使用 FolderPicker
选择文件夹。 这就是问题所在 - 用户看到一个文件夹选择器,而控件 return 进入您的代码并且您查询 Result
属性 Task
return 由 GetLogFolder
方法编辑。查询 Result
属性 导致 UI 线程停止并等待 Task
完成以获取结果。不幸的是,当用户选择文件夹时,控件想要 return 到 UI 线程以继续执行 GetLogFolder
方法的其余部分,我们有一个 死锁 。 Result
属性 停止了 UI 线程等待 Task
结果,Task
等待 UI 线程可用。两者都无法继续,因此应用程序完全冻结。
解决方案非常简单 - 使用 async
/ await
关键字。您可以在 VB.NET here with a clear example.
在您的情况下,第一步是创建按钮的 Click
处理程序方法 async
,然后将其中的代码替换为以下内容:
Dim myFolder As StorageFolder = Await GetLogFolder