我的WinForm应用需要执行具有大量执行时间的复杂查询,我没有影响力(大约10分钟) 当查询正在执行时,用户在任务管理器中看到“应用程序没有响应”,这对用户来说真的很混乱,也不是很专业...
我认为查询应该在不同的线程中执行。尝试了一些方法但很难使它真正起作用(执行查询,强制主应用程序等待结果,返回主应用程序,可能取消执行等)
我想知道你是否有自己的/良好的工作解决方案。 代码示例也非常受欢迎:)
此外,我相信可能存在一些准备使用的实用程序/框架,允许简单地执行它。
答案 0 :(得分:2)
这里最简单的方法是从BackgroundWorker中完成这项工作。 MSDN has examples for this。然后,它在工作线程上执行,包含完成/错误/等事件。它也可以支持取消,但您的操作需要编码为可中断的。
另一种方法是4.0中的Task API;但是如果你使用它,你需要自己回到UI线程(之后)。使用BackgroundWorker,这是自动的(事件在UI线程上引发)。
答案 1 :(得分:1)
如果ExecuteQuery
如果您要执行该方法,则可以执行以下操作:
void SomeMethod() {
var thread = new Thread(ExecuteQuery);
thread.Start();
}
void ExecuteQuery() {
//Build your query here and execute it.
}
如果ExecuteQuery
收到一些参数,例如:
void ExecuteQuery(string query) {
//...
}
你可以这样做:
var threadStarter = () => { ExecuteQuery("SELECT * FROM [Table]"); };
var thread = new Thread(ThreadStarter);
thread.Start();
如果要停止执行后台线程,请避免调用thread.Abort()
方法。那将是kill
线程,你不希望这样,因为你的数据库中可能会出现一些不合适的情况。
相反,您可以从bool
看到ExecuteQuery
变量,当您想要停止它时,可以从外部将其设置为True
。然后,您需要做的就是检查ExecuteQuery
中代码的某些部分(如果该变量仍为True
)。否则,请执行一些回滚以保持数据库稳定。
请务必设置bool
变量volatile
修改强>
如果您希望UI 从后台线程等待,我通常会这样做:
完成线程后,您可以停止进度条并再次启用控件。
如何知道线程何时完成?您可以使用事件。只需创建一个事件并在它完成时触发它,并在事件处理程序中做任何你想做的事情......
确保您正在从后台线程正确访问UI控件,否则会出错。
答案 2 :(得分:0)
如果您是线程新手并且任务很简单(看起来如此),您应该尝试使用standard background worker组件。