我正在尝试在Windows窗体应用程序中使用SMO来还原SQL Server数据库。我的表单有一个Button(button1)和一个TextBox(textBox1)。单击该按钮时,将调用一个函数来检查SQL Server实例是否已启动。如果它未启动,我启动实例并执行还原。这有效,但在执行函数时表单没有响应。这是我的代码:
using System;
using System.Windows.Forms;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Smo.Wmi;
namespace WindowsFormsApplication7
{
delegate void RestoreDatabaseDelegate();
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
BeginInvoke(
new RestoreDatabaseDelegate(RestoreDatabase));
}
private void RestoreDatabase()
{
//textBox1.Text = "";
try
{
Restore dbRestore = new Restore();
dbRestore.Database = "Sandbox";
dbRestore.Devices.Add(
new BackupDeviceItem(
@"C:\scripts\sandbox.bak", DeviceType.File));
Service service =
new ManagedComputer().Services["MSSQL$SQLEXPRESS2008"];
if (service.ServiceState == ServiceState.Stopped)
{
service.Start();
}
ServerConnection connection =
new ServerConnection(@"TEST\SQLEXPRESS2008");
connection.LoginSecure = true;
Server server = new Server(connection);
Database db = server.Databases[dbRestore.Database];
dbRestore.ReplaceDatabase = true;
dbRestore.Complete +=
new ServerMessageEventHandler(RestoreComplete);
dbRestore.Information +=
new ServerMessageEventHandler(RestoreInformation);
dbRestore.SqlRestoreAsync(server);
}
catch (Exception ex)
{
/*textBox1.Text +=
(ex.Message + Environment.NewLine);*/
}
}
private void RestoreComplete(
object sender, ServerMessageEventArgs e)
{
/*textBox1.Text +=
(e.Error.Message + Environment.NewLine);*/
}
private void RestoreInformation(
object sender, ServerMessageEventArgs e)
{
/*textBox1.Text +=
(e.Error.Message + Environment.NewLine);*/
}
}
}
有没有办法在恢复(和SQL Server实例启动)进行过程中保持表单的响应?我做错了什么?
答案 0 :(得分:2)
如果UI线程被阻止,UI无法抽取窗口消息(因此将显示无响应)。相反,请查看BackgroundWorker
,它允许轻松地将较长时间运行的任务推送到工作线程(但仍然推动对UI的更新)。
答案 1 :(得分:1)
查看BackgroundWorker课程。它将允许您在另一个线程上执行长时间运行的操作,而不会阻塞UI线程。
答案 2 :(得分:1)
AFAIR在应用程序类中有一个类似 ProcessMessages 的方法,当您的应用程序的所有者进程响应不佳时,您可以使用该方法将消息处理到窗口即使你在另一个线程上做某事并且与主线程没有任何关系。
等待更多
是的Application.DoEvents();
提升您的流程或主线程(UI所有者)可能会有所帮助。