Winforms的异步加载 [英] Async loading for winforms
问题描述
在(Android)应用中,在用户与界面交互时加载和构建ListView是很常见的.但是,在Winforms中,趋势似乎是单击按钮并等待结果完全加载,然后用户才能继续浏览该应用程序.
In (Android) Apps it is quite common to have ListViews loading and being built while the user is interacting with the interface. In Winforms however the tendency seems to be clicking a button and waiting for the result to be fully loaded before the user can continue navigating through the application.
由于我当前正在使用的数据库访问速度很慢,因此我想在异步方法中使用数据库,以使用户能够与接口进行交互,而数据并没有完全加载和显示.
Since the database access that i am currently using is quite slow, i would like to use the database in async methods to enable the user to keep interacting with the interface, while the data is not fully loaded and displayed.
例如,我想在Form_Load事件中启动一个异步方法以保持收集数据.当此方法完成后,我想将数据绑定到某些控件-暂时不会更改任何功能.因此,我希望用户在处理应用程序时不要注意到任何区别(除了显示的数据与否).
For example i would like to start an asynchronous method in my Form_Load event to keep gathering data. When this method completes, i want to bind the data to some controls - this will (for now) not change the functionality at all. Thus i want the user not to notice any difference (except for the data being shown or not) when handling the application.
我应该在哪里放置await关键字来完成此操作?我无法将其放在Load事件中,因为这需要完成,应用程序才能正常"运行.
Where am i supposed to place the await keyword to accomplish this? I can't place it in my Load event since this needs to complete for the application to behave "normally".
甚至异步方法是否有可能使Windows窗体完全反作用而并非所有方法都已完成,或者我是否出于自己的目的考虑错误"功能?
Is it even possible with async methods to have windows forms being fully reactional while not all methods completed, or am i looking at the 'wrong' functionality for my purposes?
谢谢.
按照Srirams的提示,我使load-event本身成为一个异步子程序,效果很好.以下是一些简单的示例代码,显示了所需的行为:
Following Srirams hint, I made the load-event itself an async sub which worked out well. Here is some simple sample code which shows the desired behaviour:
Public Class DelayedLoadingWindow
Private Async Sub DelayedLoadingWindow_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim awaitedResultOne As Task(Of String) = GetDataOneAsync()
Label1.Text = Await awaitedResultOne
Dim awaitedResultTwo As Task(Of String) = GetDataTwoAsync()
Label2.Text = Await GetDataTwoAsync()
Dim awaitedResultThree As Task(Of String) = GetDataThreeAsync()
Label3.Text = Await GetDataThreeAsync()
Me.Text = "DONE"
End Sub
Public Async Function GetDataOneAsync() As Task(Of String)
Await Task.Delay(2000)
Return "Async Methods"
End Function
Public Async Function GetDataTwoAsync() As Task(Of String)
Await Task.Delay(2000)
Return "are"
End Function
Public Async Function GetDataThreeAsync() As Task(Of String)
Await Task.Delay(2000)
Return "running!"
End Function
End Class
推荐答案
我应该在哪里放置await关键字来完成此操作?一世无法将其放置在我的Load事件中,因为这需要完成应用程序的行为正常".
Where am i supposed to place the await keyword to accomplish this? I can't place it in my Load event since this needs to complete for the application to behave "normally".
为什么不能在加载事件处理程序中等待?如果您使用 async
修饰符标记该方法,则可以执行此操作.
Why can't you await inside load event handler? You can do that if you mark the method with async
modifier.
private async void Form_Load(object sender, EventArgs e)
{
//Do something
var data = await GetDataFromDatabaseAsync();
//Use data to load the UI
}
这样,您可以使UI保持响应状态,还可以异步执行耗时的工作. GetDataFromDatabaseAsync
必须是异步的(不应阻止调用线程).
This way, you can keep the UI responsive and also execute the time consuming work asynchronously. GetDataFromDatabaseAsync
has to be asynchronous (should not block the calling thread).
如果这不能回答您的问题,请更具体.
If this doesn't answers your question, please be more specific.
这篇关于Winforms的异步加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!