异步设置网格






4.33/5 (2投票s)
带有进度指示器的自定义异步设置。
引言
如果需要一个可以读取 XML 设置文件 (SetupScripts.xml) 并在其中异步运行定义的方法或脚本的设置组件,那么此 Setup Grid 组件正是您所寻找的。要使用此组件,可以在 SetupScripts.xml 中定义程序集中的方法、批处理文件或 T-SQL 文件的路径,并且我们可以调用 StartSetup()
来异步执行它们。这意味着,当设置正在进行时,不会暂停其他操作。
解决方案
SetupGridUC
是一个 UserControl,包含一个 DataGridView
,用于在设置运行时显示脚本和进度状态。 使用 SetupGridUC
组件的典型场景如下所示
- 使用
Load()
方法从 SetupScripts.xml 文件初始化SetupGridUC
。 - 使用
SetupGridUC
的StartSetup()
方法启动设置,并在启动时使用StopSetup(false)
。 - 为了在设置开始或结束时执行某些操作(例如,禁用按钮),请使用以下事件
void stpGrid_ProgressFinished(object sender, EventArgs e)
在设置完成时调用。void stpGrid_ProgressStarted(object sender, EventArgs e)
在设置开始时调用。
实现
StartSetup()
方法通过使用 BeginInvoke()
调用 SetupGridUC
组件的 ExecuteScript()
方法来异步启动设置过程。
private MethodDelegate methodDelegate;
...
asyncResult = methodDelegate.BeginInvoke(null, null);
使用视觉组件(例如,从另一个执行线程刷新 DataGridView
)可能会导致 Cross-thread operation not valid 异常。为了绕过此异常,应使用组件的 Invoke()
方法。 SafeInvoke()
使用组件的 Invoke()
方法来调用组件中的一个无参数方法(void MethodName()
委托)
private delegate void VoidDelegate();
...
private void SafeInvoke(Control ctrl, VoidDelegate delgt)
{
if (ctrl.InvokeRequired)
{
VoidDelegate d = new VoidDelegate(delgt);
ctrl.Invoke(d, new object[] { });
}
}
要在另一个线程中刷新 asyncSetupGrid
,请使用 SafeInvoke()
方法,如下所示
private void command_Progress(object sender, ProgressEventArgs e)
{
/// Call Refresh method of asyncSetupGrid using Invoke
SafeInvoke(asyncSetupGrid, Refresh);
}
注意: void command_Progress
事件是从另一个线程调用的,因此视觉组件应使用 Invoke()
来调用方法。
脚本或方法可以在 SetupScripts.xml 中定义,如下所示
<tblSetupScripts>
<ID>2</ID>
<Name>S3</Name>
<Title>Execute SQLQuery.sql against Database</Title>
<Script>SQLQuery.sql</Script>
<Kind>SQLScript</Kind>
</tblSetupScripts>
标签含义
<Name>:
Name tag should be a unique name that user can assign to the script to be run
<Title>:
Title tag is an explanation for the script
<Script>:
Script tag meanings depend on <Kind> tag that can be set as follows:
<Kind>Method</Kind>
<Script>
{Assembly file name}, {Namespace. class name}, {Method name}
/// <summary>
/// This method is being called using reflection.
/// It is defined in SetupScripts.xml file.
/// Developer should pass following two delegate parameters
/// to it that are doing some actions on calling SetupGrid object.
/// </summary>
/// <param name="doProgress"> This method sets progress bar
/// status in the subject row of the SetupGrid </param>
/// <param name="doHalt"> This method returns true
/// if user stops the setup process </param>
public void Mehtod(SetupGrid.ScriptCommands.ProgressDelegate doProgress,
SetupGrid.ScriptCommands.HaltDelegate doHalt)
{
...
}
</Script>
<Kind>SQLScript</Kind>
<Script> {Path of SQL script to be executed}
The T-SQL commands are separated using 'Go'
command from each other. For example:
...
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
...
</Script>
<Kind>BatchFile</Kind>
<Script> { The path and file name of the Batch file to be executed}
The batch file execution will open a Command Prompt
window and waits the command is finished.
</Script>
部署
此示例包含两个程序集
- Main.exe 作为承载 SetupGrid 组件的可执行文件。
- SetupGrid.dll 作为包含 SetupGridUC 组件的库。
为了测试 SQL 脚本,请在 SQL Server 中创建一个数据库,并将适当的连接设置添加到 Properties/Settings.settings 文件中的数据库中。