【问题标题】:Monitor.TryEnter just working the first timeMonitor.TryEnter 第一次工作
【发布时间】:2014-11-26 11:53:12
【问题描述】:

我有一个插件,它使用一个 SAP Business One SDK。我的插件有一些线程,每个都有事务。 SAP Business One SDK 仅按会话接受一个事务,如果正在使用事务,则我无法启动事务。

其实我在 StartTransaction 方法中有这个控件:

StarTransaction()
{
    if (!Monitor.TryEnter(syncRoot, new TimeSpan(0, 0, 0, 10)))
        throw new TimeoutException("Transaction is busy, Try Again in some seconds");

    mCompany.StartTransaction();
}

EndTransaction()
{
    try
    {
        mCompany.EndTransaction(endType);
    }
    finally
    {
        Monitor.Exit(syncRoot);
    }
}

在屏幕上,我发现了这个命令(示例):

catch (TimeoutException Ex)
{
    AddOn.Mensagens.ShowStatusBarMessage('Please, try again');
}

实际上这段代码有效,但只有效一次。 在此消息之后,我再次启动该过程,返回的消息将是相同的“(再试一次)”。

我使用了错误的 TryEnter 或忘记发布某些内容?我无法完成交易,因为可能正在使用另一个进程。

任何帮助将不胜感激。

【问题讨论】:

  • 您需要提供更好的代码示例。从行为来看,很明显由于某种原因没有调用EndTransaction() 方法,或者在错误的线程上调用了它。但是这里没有足够的上下文来理解为什么会这样。请注意,您必须从获取锁的同一线程调用Monitor.Exit();许多异步 API(可能是您在此处使用的 API)将在与开始操作的线程不同的线程中引发完成事件。但是,如果这里是这种情况,您应该会在 Monitor.Exit() 上看到一个异常。

标签: c# transactions locking


【解决方案1】:

您忘记释放锁定。应该是这样的

StarTransaction()
{
    if (!Monitor.TryEnter(syncRoot, new TimeSpan(0, 0, 0, 10)))
        throw new TimeoutException("Transaction is busy, Try Again in some seconds");
    // if we are here, then lock was successfully taken
    try
    {
        mCompany.StartTransaction();
    }
    finally
    {
        Monitor.Exit(syncRoot);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    相关资源
    最近更新 更多