Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.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# 什么是正确的方法来处理需要;“长时间”;完成?_C#_Database_Sql Server 2005_Multithreading_Visual Studio 2005 - Fatal编程技术网

C# 什么是正确的方法来处理需要;“长时间”;完成?

C# 什么是正确的方法来处理需要;“长时间”;完成?,c#,database,sql-server-2005,multithreading,visual-studio-2005,C#,Database,Sql Server 2005,Multithreading,Visual Studio 2005,我在VisualStudio2005Pro中创建了一个Winforms应用程序,它使用SqlConnection/SqlCommand/SqlDataAdapter类连接到SQLServer2005数据库以提取数据。我的数据库中有存储过程来将数据返回给我 处理需要“很长时间”才能完成的查询的最佳方法是什么?(即,足够长的时间,用户开始认为有问题)。当前,我的应用程序将锁定,直到查询完成或查询超时。显然,这是不可接受的 我至少想要一个有“停止”按钮的进度表。进度表甚至不需要做任何有用的事情,作为一

我在VisualStudio2005Pro中创建了一个Winforms应用程序,它使用SqlConnection/SqlCommand/SqlDataAdapter类连接到SQLServer2005数据库以提取数据。我的数据库中有存储过程来将数据返回给我

处理需要“很长时间”才能完成的查询的最佳方法是什么?(即,足够长的时间,用户开始认为有问题)。当前,我的应用程序将锁定,直到查询完成或查询超时。显然,这是不可接受的

我至少想要一个有“停止”按钮的进度表。进度表甚至不需要做任何有用的事情,作为一个耐心等待的提示就足够了

更好的警告是这样的:“这将返回140000行数据。是否继续?”


我知道这可能需要线程,但如何实现?

要实现您的警告,您可以首先发出COUNT()查询,该查询不仅会返回用户将要获取的行数,而且可能会开始缓存数据。

您可能需要创建另一个表来记录查询的执行时间。这样你可以说“上一次这个过程花费了X个时间。”这将为他们提供一个大概的估计时间。否则,您必须运行查询才能获得一个可能需要较长时间的计数。

好,首先,我建议尝试使查询更快。首先要检查的是确保您有适当的索引。网上有大量关于正确使用索引的文章

如果在所有这些之后,您的查询仍然太慢,那么您可能必须切换到使用数据库游标

使用光标,您可以一次读取一个结果,然后拖动它们。这将使您有机会显示进度条


如果您坚持当前的查询模型,仅使用线程绘制进度条,则进度条与正在完成的工作无关,看起来也不正确。

您将希望利用线程。当用户发出获取数据的信号时,您可以生成一个新线程来获取数据,同时在主窗体上显示一个throbber。当线程返回时,您可以做出反应并显示结果

确保查询得到优化是第一步,但之后,您必须使用线程,而.NET有针对这些情况的解决方案

下面是一个简单的C#2.0示例:

    private void Form_Load(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        //change UI to reflect we're doing this
        bw.RunWorkerAsync();
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        //SQL Work
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //Let the user know we're done
    }

我在创建长文件时使用RunWorker和ProgressBar


我使用的一个技巧是在设置ProgressBar时找到一个与文件长度相同的代理。例如,ProgressBar可能基于上次运行函数时文件中的行数(可能保存在长文件中)。进度条或类似的进度条不一定要精确。

对于进度条,请查看选框样式。如果由于某种原因无法获取实际进度报告(也就是说,如果按照dicroce建议的方式使用游标不可行/太慢/不管怎样),您可以使用字幕进度条显示您的UI仍在响应,并且您没有忘记用户


记住Jakob Nielsen的规则:如果你需要超过250毫秒(?)才能返回给用户,他们会担心出了什么问题。通常,您的按钮应该运行任何必要的验证(快速!),然后显示一些告诉用户“我正在工作”的内容,并将控制返回到UI循环。

另一方面,计数可能需要很长时间,并且需要自己的进度条!没错。。。但这是一个想法:)