且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在应用程序启动时异步读取文件?

更新时间:2022-11-06 12:44:03

这是 async void $ c $的一大问题c>方法 - 方法在完成之前返回,并且调用者无法知道该方法仍在工作。



Application class引发 Startup 事件。处理程序返回时 - 在您的示例中第一个等待调用 - 然后调用私有 DoStartup 方法。这个方法读取你的代码尚未设置的 StartupUri ,所以它无关。



正如您所发现的那样,如果您移动分配 StartupUri 的行之前第一个等待调用,然后它将按预期工作。



理想情况下,您应该将 async 代码移动到任务 - 调整方法。然后,您可以将该任务存储在一个字段中,稍后代码可以等待它以确保它已完成。



避免异步空方法你被劫持了 [ ^ ]
This is one of the big problems with async void methods - the method returns before it has completed, and the caller has no way of knowing that the method is still doing work.

The Application class raises the Startup event. When the handler returns - at the first await call in your example - it then calls the private DoStartup method. This method reads the StartupUri, which you code hasn't set yet, so it has nothing to do.

As you discovered, if you move the line which assigns the StartupUri before the first await call, then it will work as expected.

Ideally, you should move the async code to a task-retuning method. You can then store that task in a field, and later code can await it to ensure that it has completed.

Avoid async void methods | You’ve Been Haacked[^]


我不确定你的代码,但我认为你是在应用程序启动阶段的早期这样做的。



如果你有一个显示状态的窗口,为什么不先让窗口加载并使用进度显示进行异步调用?我已经实现了一些演示如何工作的演示:



例如,参见 MainWindow.cs - > FilterTreeView.zip中的已加载事件演示:



C#/ VB.Net中的高级WPF TreeViews n的第3部分 [ ^ ]



下载:C#/ VB.Net中的高级WPF TreeViews n [ ^ ]
I am not sure about your code but I think you are doing this to early in the start-up phase of the application.

If you have a window to show with a status, why don't let the window load first and do the async call with a progress display? I have implemented a few demos that show how this could work:

See, for example, MainWindow.cs -> Loaded Event in FilterTreeView.zip demo:

Advanced WPF TreeViews in C#/VB.Net Part 3 of n[^]

Downloads: Advanced WPF TreeViews in C#/VB.Net Part 3 of n[^]


尝试将窗口作为资源加载到异步方法的延续部分。

Try loading your window as a resource in the continuation part of the async method.

protected override async void OnStartup( StartupEventArgs e )
{
	base.OnStartup( e );
	Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
	LogsEmailer logsEmailer = new LogsEmailer();
        //StartupUri = new Uri( "./View/MainWindow.xaml", UriKind.Relative );
	string testString = await logsEmailer.TestReadFileAsync( Path.Combine( logsFolder, "TestFile.txt" ) );
	Uri startUpUri = new Uri("MainWindow.xaml", UriKind.Relative);
        MainWindow=LoadComponent(startUpUri)as Window;
        MainWindow.Show();
}