gpt4 book ai didi

ado.net - 微软机器人和 Sql

转载 作者:行者123 更新时间:2023-12-04 06:42:11 25 4
gpt4 key购买 nike

我在使用 SQL 实现 CCR 时遇到问题。似乎当我逐步执行我的代码时,我试图执行的更新和插入效果很好。但是当我在没有任何断点的情况下通过我的界面运行时,它似乎正在工作,它显示了插入、更新,但在运行结束时,数据库中没有任何更新。

每次我从池中拉出一个新线程并且它可以工作时,我都会在我的代码中添加一个暂停......但这违背了异步编码的目的,对吗?我希望我的界面更快,而不是放慢速度......

任何建议......这是我的代码的一部分:

我使用两个帮助类来设置我的端口并得到响应......

    /// <summary> 
/// Gets the Reader, requires connection to be managed
/// </summary>
public static PortSet<Int32, Exception> GetReader(SqlCommand sqlCommand)
{
Port<Int32> portResponse = null;
Port<Exception> portException = null;
GetReaderResponse(sqlCommand, ref portResponse, ref portException);
return new PortSet<Int32, Exception>(portResponse, portException);
}

// Wrapper for SqlCommand's GetResponse
public static void GetReaderResponse(SqlCommand sqlCom,
ref Port<Int32> portResponse, ref Port<Exception> portException)
{
EnsurePortsExist(ref portResponse, ref portException);
sqlCom.BeginExecuteNonQuery(ApmResultToCcrResultFactory.Create(
portResponse, portException,
delegate(IAsyncResult ar) { return sqlCom.EndExecuteNonQuery(ar); }), null);
}

然后我做这样的事情来排队我的电话......
        DispatcherQueue queue = CreateDispatcher();
String[] commands = new String[2];
Int32 result = 0;
commands[0] = "exec someupdateStoredProcedure";
commands[1] = "exec someInsertStoredProcedure '" + Settings.Default.RunDate.ToString() + "'";

for (Int32 i = 0; i < commands.Length; i++)
{
using (SqlConnection connSP = new SqlConnection(Settings.Default.nbfConn + ";MultipleActiveResultSets=true;Async=true"))
using (SqlCommand cmdSP = new SqlCommand())
{
connSP.Open();
cmdSP.Connection = connSP;
cmdSP.CommandTimeout = 150;
cmdSP.CommandText = "set arithabort on; " + commands[i];

Arbiter.Activate(queue, Arbiter.Choice(ApmToCcrAdapters.GetReader(cmdSP),
delegate(Int32 reader) { result = reader; },
delegate(Exception e) { result = 0; throw new Exception(e.Message); }));
}
}

其中 ApmToCcrAdapters 是我的辅助方法所在的类名...

问题是当我在调用 Arbiter.Activate 之后暂停我的代码并检查我的数据库时,一切看起来都很好......如果我摆脱暂停广告运行我的代码,数据库没有任何 react ,也没有异常(exception)要么被扔...

最佳答案

这里的问题是您正在调用 Arbiter.Activate在你的两个范围内using block 。不要忘记您创建的 CCR 任务已排队,并且当前线程继续...超过 using 的范围 block 。您创建了一个竞争条件,因为 Choice必须在 connSP 之前执行和 cmdSP正如您在调试时观察到的那样,这只会在您干扰线程计时时发生。

相反,如果您要在 Choice 的处理程序委托(delegate)中手动处理处置,这个问题将不再发生,但是这使得代码很脆弱,很容易忽略处理。

我建议实现 CCR 迭代器模式并使用 MulitpleItemReceive 收集结果这样您就可以保留您的using陈述。它使代码更清晰。在我的脑海中,它看起来像这样:

private IEnumerator<ITask> QueryIterator(
string command,
PortSet<Int32,Exception> resultPort)
{
using (SqlConnection connSP =
new SqlConnection(Settings.Default.nbfConn
+ ";MultipleActiveResultSets=true;Async=true"))
using (SqlCommand cmdSP = new SqlCommand())
{
Int32 result = 0;
connSP.Open();
cmdSP.Connection = connSP;
cmdSP.CommandTimeout = 150;
cmdSP.CommandText = "set arithabort on; " + commands[i];

yield return Arbiter.Choice(ApmToCcrAdapters.GetReader(cmdSP),
delegate(Int32 reader) { resultPort.Post(reader); },
delegate(Exception e) { resultPort.Post(e); });
}

}

你可以像这样使用它:
var resultPort=new PortSet<Int32,Exception>();
foreach(var command in commands)
{
Arbiter.Activate(queue,
Arbiter.FromIteratorHandler(()=>QueryIterator(command,resultPort))
);
}
Arbiter.Activate(queue,
Arbiter.MultipleItemReceive(
resultPort,
commands.Count(),
(results,exceptions)=>{
//everything is done and you've got 2
//collections here, results and exceptions
//to process as you want
}
)
);

关于ado.net - 微软机器人和 Sql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4107461/

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