gpt4 book ai didi

c++ - ADO:如何使用取消功能同步执行查询?

转载 作者:行者123 更新时间:2023-11-28 03:54:38 24 4
gpt4 key购买 nike

现在我有一个使用 ADO 运行查询并返回 recordset 的函数:

Recordset Execute(Connection connection, String commandText)
{
//[pseudo-code]
Recordset rs = new Recordset();
rs.CursorLocation = adUseClient;
rs.CursorType = adOpenForwardOnly;
rs.Open(commandText, connection,
adOpenForwardOnly, //CursorType; the default
adLockReadOnly, //LockType
adCmdText);

return rs;
}

这很好。它同步运行,并返回查询的记录集。

现在我想要一个类似的版本,显示 ProgressDialog ,为用户提供取消长时间运行的查询的能力:

Recordset Execute(HWND parenthWnd, String caption, Connection connection, String commandText)
{
//[pseudo-code]

//Construct a progressDialog and show it
IProgressDialog pd = new ProgressDialog();
pd.SetTitle(caption); //e.g. "Annual Funding Report"
pd.SetCancelMsg("Please wait while the operation is cancelled");
pd.StartProgressDialog(parenthWnd, null, PROGDLG_MODAL | PROGDLG_NOTIME | PROGDLG_NOMINIMIZE, null);
pd.SetLine(1, "Querying server", False, null);
try
{
//Query the server
Recordset rs = new Recordset();
rs.Open(commandText, connection,
adOpenForwardOnly, //CursorType
adLockReadOnly, //LockType
adCmdText | adAsyncExecute);

while (rs.State and (adStateConnecting+adStateExecuting+adStateFetching) <> 0)
{
if pd.HasUserCancelled()
throw new EUserCancelledOperationException();

Sleep(100);
};

finally
{
//Hide and destroy the progress dialog
pd.StopProgressDialog();
pd = null;
}

//Now we have our results for the client
return rs;
}

检查用户是否取消操作的方法是定期询问进度对话框用户是否按下了取消按钮:

pd.HasUserCancelled(); //returns true if user has clicked Cancel

现在我面临着如何定期检查用户是否已取消(并了解查询是否已完成,或是否发生错误),以及如何成为一名优秀的程序员并在不进行轮询的情况下进行操作。

知道发生错误的唯一方法是在 Recordset 的 FetchCompleteEvent 上有一个处理程序:

pError
An Error object. It describes the error that occurred if the value of adStatus is adStatusErrorsOccurred; otherwise it is not set.

adStatus
An EventStatusEnum status value. When this event is called, this parameter is set to adStatusOK if the operation that caused the event was successfull, or to adStatusErrorsOccurred if the operation failed.

Before this event returns, set this parameter to adStatusUnwantedEvent to prevent subsequent notifications.

pRecordset
A Recordset object. The object for which the records were retrieved.

所以这意味着我将不得不让我的函数构造一个辅助对象,这样我就可以有一个 FetchComplete 处理程序。但是我必须阻止我的 synchronous 函数立即返回。然后我们进入 MsgWaitForSingleObject,这是出了名的难以正确使用。

所以我要寻求帮助或预制代码。


我应该更明确:我正在寻找具有此方法签名的函数实现:

Recordset ExecuteWithCancelOption(Connection connection, String commandText)

显示一个带有取消按钮的对话框。

挑战在于函数现在必须创建实现该目标所需的任何内容。如果这涉及一个隐藏的表格,上面有一个计时器等等 - 好的。

但我正在寻找一个显示取消 按钮的同步 函数。

并且该函数将成为

的近似(或精确)替代品
Recordset Execute(Connection connection, String commandText)

考虑到 Windows 上的实际考虑,我需要为该函数提供一个父窗口句柄,它将其对话框作为其父级:

Recordset ExecuteWithCancelOption(HWND parentHwnd, Connection connection, String commandText)

鉴于这将是一个可重用的函数,我将让调用者提供将要显示的文本:

Recordset ExecuteWithCancelOption(HWND parenthWnd, String caption, Connection connection, String commandText)

鉴于这些都是我的 TADOHelper 类中的类函数,我可以给它们取相同的名称,并让它们彼此重载:

Recordset Execute(HWND parenthWnd, String caption, Connection connection, String commandText)

我认为在 Delphi 以外的语言中,匿名代表很有帮助。但我仍然害怕不得不处理 MsgWaitForMultipleObjects

最佳答案

  1. 进度信息和优雅地取消查询可能不适用于每个数据库引擎。他们需要数据库支持,包括服务器端和客户端。例如,Oracle 允许取消查询,但没有“进行中”信息,而是读取 V$SESSION_LONGOPS View 。当然,您可以终止 session ,但它会回滚整个 session ,而不仅仅是取消给定查询的执行。
  2. 通常如果数据库支持这种功能,查询将在一个单独的线程中运行,等待结果。这样主线程仍然可以获取用户输入或读取和显示进度信息(除非在某种回调中返回)。如果用户取消查询,则发出适当的调用以停止操作,允许查询线程返回,通常该线程将收到一个状态代码,说明发生了什么。
  3. 了解 ADO 如何实现异步操作:http://msdn.microsoft.com/en-us/library/ms681467(VS.85).aspx
  4. 还有一个 FetchProgress() 事件可以帮助您,如果您不想使用线程方式(甚至取消查询,如果可能的话)

关于c++ - ADO:如何使用取消功能同步执行查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4127680/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com