首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Microsoft Robotics和Sql

Microsoft Robotics和Sql
EN

Stack Overflow用户
提问于 2010-11-05 23:37:50
回答 1查看 114关注 0票数 2

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

每当我从我的池中拉出一个新的线程时,我都会给我的代码添加一个暂停,并且它工作了……但是这违背了异步编码的目的,对吧?我想让我的界面更快,而不是变慢。

任何建议..。下面是我的代码的一部分:

我使用了两个helper类来设置我的端口并得到一个响应...

代码语言:javascript
复制
    /// <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);
    }

然后我做一些类似的事情来排队我的电话...

代码语言:javascript
复制
        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之后立即暂停代码并检查我的数据库时,一切看起来都很好……如果我取消暂停并运行代码,数据库不会发生任何变化,也不会抛出任何异常……

EN

回答 1

Stack Overflow用户

发布于 2010-12-02 04:15:01

这里的问题是,您在两个using块的作用域中调用Arbiter.Activate。不要忘记,您创建的CCR任务已排队,当前线程仍在继续...正好超出了using块的作用域。您已经创建了一个竞争条件,因为Choice必须在connSPcmdSP被释放之前执行,而这只会在您干扰线程计时时发生,正如您在调试时观察到的那样。

相反,如果您在Choice的处理程序委托中手动处理处置,这个问题就不会再发生,但是这会导致代码脆弱,很容易忽略处置。

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

代码语言:javascript
复制
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); });
    }

}

你可以像这样使用它:

代码语言:javascript
复制
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
        }
    )
);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4107461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档