Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# winforms的异步加载_C#_.net_Vb.net_Asynchronous_Visual Studio 2013 - Fatal编程技术网

C# winforms的异步加载

C# winforms的异步加载,c#,.net,vb.net,asynchronous,visual-studio-2013,C#,.net,Vb.net,Asynchronous,Visual Studio 2013,在(Android)应用程序中,在用户与界面交互时加载和构建ListView是很常见的。然而,在Winforms中,趋势似乎是单击按钮,等待结果完全加载,然后用户才能继续在应用程序中导航 由于我当前使用的数据库访问速度非常慢,因此我希望以异步方法使用数据库,以便用户能够在数据未完全加载和显示的情况下保持与界面的交互 例如,我想在Form_Load事件中启动一个异步方法,以保持数据收集。当这个方法完成时,我想将数据绑定到一些控件上——这(目前)根本不会改变功能。因此,我希望用户在处理应用程序时不要

在(Android)应用程序中,在用户与界面交互时加载和构建ListView是很常见的。然而,在Winforms中,趋势似乎是单击按钮,等待结果完全加载,然后用户才能继续在应用程序中导航

由于我当前使用的数据库访问速度非常慢,因此我希望以异步方法使用数据库,以便用户能够在数据未完全加载和显示的情况下保持与界面的交互

例如,我想在Form_Load事件中启动一个异步方法,以保持数据收集。当这个方法完成时,我想将数据绑定到一些控件上——这(目前)根本不会改变功能。因此,我希望用户在处理应用程序时不要注意到任何差异(显示的数据除外)

我应该在哪里放置wait关键字来完成这个任务?我无法将其放入我的加载事件中,因为这需要完成,应用程序才能“正常”运行

异步方法是否可能使windows窗体在没有完成所有方法的情况下完全响应,或者我是否考虑了“错误”的功能

先谢谢你

编辑:根据Srirams的提示,我将load事件本身设置为一个异步子事件,这很好地解决了问题。下面是一些简单的示例代码,显示了所需的行为:

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
我应该在哪里放置wait关键字来完成这个任务?我 无法将其放置在“我的加载”事件中,因为这需要为 应用程序的行为“正常”

为什么不能在load事件处理程序中等待?如果使用
async
修饰符标记该方法,则可以执行此操作

private async void Form_Load(object sender, EventArgs e)
{
    //Do something
    var data = await GetDataFromDatabaseAsync();
    //Use data to load the UI
}
通过这种方式,您可以保持UI的响应性,还可以异步执行耗时的工作
GetDataFromDatabaseAsync
必须是异步的(不应阻止调用线程)


如果这不能回答您的问题,请更加具体。

您可以使用BackgroundWorker控件

您只需将BackgroundWorker控件放在表单上(在我们的例子中是backgroundWorker1),BackgroundWorker控件还支持取消、RunWorkerCompleted等

private SlowLoadingForm frm;

private void startAsyncButton_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    frm = new SlowLoadingForm();
    frm.show();
    Application.Run(frm);
}

为什么不使用
BackgroundWorker
?@hw:我已经用测试项目检查了我的代码,并且它工作得很好。虽然这不会阻止UI本身,但是在事件处理程序完成之前,肯定不会加载有问题的表单,而在
GetDataFromDatabaseAsync()之前
完成。@BenRobinson根据OP所说,因此我希望用户不要注意到任何差异(除了显示的数据与否),我想这很好。你还能做些什么呢?@BenRobinson:不,WinForms在点击第一个
wait
时会考虑
Form\u Load
事件“done”。这是一个完全恰当的解决方案;只需确保在第一个代码>等待< /COD>之前将表单初始化为“空状态”UI,然后在第一个代码>等待< /COD>之后的代码应该只是更新UI以包含数据。@ StephenCleary,我想如果我们将这种情况视为OOP中的一般情况,发生的事情是,在加载表单的处理程序之后,您不知道发生了什么,那么它就不能等待处理程序了。@TommyMoore您是什么意思?您确定对async/await了解得足够多吗?是什么使
Task
成为一个健壮而整洁的任务,而async/await不是?DoWork在与UI线程不同的线程中工作,没有消息循环。这将以惊人的方式失败。@Steve:我只是忘了添加Application.Run(frm),现在我已经更新了代码,它现在工作得很好,我已经用我的测试项目检查了它。谢谢你纠正我的错误。我没有否决你,但这仍然是错误的@Steve:代码有什么问题吗Steve,我很想知道,我已经用我的测试项目对它进行了测试,如果你愿意,我可以发送给你。pl.让我知道问题所在。@Vaibhav现在您的
dowwork
事件除了发送消息之外,无法执行任何其他工作,这会使
BackgroundWorker
无用。