【问题标题】:ThreadPool and GUI wait questionThreadPool 和 GUI 等待问题
【发布时间】:2010-09-27 09:08:29
【问题描述】:

我是线程新手,需要帮助。我有一个数据输入应用程序需要花费大量时间来插入新记录(即 50-75 秒)。所以我的解决方案是通过 ThreadPool 发送一个插入语句,并允许用户在插入运行时开始输入记录的数据,该插入返回一个新的记录 ID。我的问题是用户可以在从插入返回新 ID 之前点击保存。

我尝试放入一个布尔变量,当可以安全保存时,该变量通过来自该线程的事件设置为 true。然后我输入了

while (safeToSave == false)  
{  
    Thread.Sleep(200)  
}  

我认为这是个坏主意。如果我在胎面返回之前运行 save 方法,它就会卡住。

所以我的问题是:

  1. 有更好的方法吗?
  2. 我在这里做错了什么?

感谢您的帮助。
道格

编辑以获取更多信息:

它正在插入一个非常大(接近最大大小)的 FoxPro 数据库。该文件有大约 200 个字段和几乎一样多的索引。
在你问之前,不,我不能像以前那样改变它的结构,而且有大量的遗留代码在攻击它。第一个问题是,为了获得一个新的 ID,我必须首先在表中找到 max(id),然后对其进行递增和校验。这大约需要 45 秒。然后第一个插入很简单,插入新的 id 和 enterdate 字段。该表不/不能放入 DBC 中,因此排除了自动生成的 id 等。

@joshua.ewer
你的过程是正确的,我认为短期内我只会禁用保存按钮,但我会研究你将其传递到队列中的想法。您是否有任何关于 MSMQ 的参考资料需要我看一下?

【问题讨论】:

    标签: c# threadpool deadlock


    【解决方案1】:

    1) 很多:),例如,您可以在线程插入对象时禁用“保存”按钮,或者您可以设置一个处理“保存请求”队列的线程工作器(但我认为问题在这里是用户想要修改新创建的记录,所以禁用按钮可能会更好)

    2) 我认为我们需要更多代码才能理解......(或者可能是同步问题,我也不是线程的错误粉丝)

    顺便说一句,我只是不明白为什么插入需要这么长时间..我认为您应该先检查该代码!

    【讨论】:

      【解决方案2】:

      包括您在内的其他所有人都解决了核心问题(插入时间、您为什么要进行插入,然后进行更新),因此我将只关注您提出的解决方案的技术问题。所以,如果我的流程正确:

      • 线程 1:开始数据输入 记录

      • 线程 2:后台调用 DB 以检索新 Id

      • 保存按钮始终处于启用状态, 如果用户尝试在 Thread 之前保存 2 完成,你让 #1 休眠 200 毫秒?

      最简单但不是最好的答案是禁用按钮,并让该线程向启用该按钮的委托发送callback。在您确定设置正确之前,他们无法启动更新操作。

      不过,我认为更好的解决方案(尽管如果您只是为 FoxPro 构建 Q&D 前端可能会被夸大其词)是将这些保存操作放入队列中。用户可以尽快键入,然后将请求放入 MSMQ 之类的东西中,它们可以在自己的时间异步完成。

      【讨论】:

        【解决方案3】:

        使用future 而不是原始线程池操作。执行未来,允许用户做任何他们想做的事情,当他们点击第二条记录的保存时,从未来请求值。如果第一次插入已经完成,您将立即获得 ID,并且第二次插入将被允许开始。如果还在等待第 1 次操作,future 会阻塞,直到可用,然后才能执行第 2 次操作。

        除非用户比操作慢,否则你不会节省任何时间。

        【讨论】:

          【解决方案4】:

          首先,您可能应该找出并解决插入需要这么长时间的原因......对于任何现代数据库来说,50-75 秒对于单行插入来说都是不合理的,并且表明需要进行其他操作已解决,例如索引或阻塞...

          其次,为什么要在获得数据之前插入记录?通常,对数据输入应用程序进行编码,以便在从用户那里收集到所有插入所需的数据之前,不会尝试插入。你这样做是因为你试图先从数据库中取回新的 ID,然后稍后用用户输入的数据“更新”新的空记录?如果是这样,几乎每个数据库供应商都有一种机制,您可以在不知道新 ID 的情况下只执行一次插入操作,并且让数据库也返回新 ID……您使用的是什么供应商数据库?

          【讨论】:

            【解决方案5】:

            这样的解决方案是否可行:

            在用户开始添加之前预先计算唯一 ID。保留已在表中但实际上是占位符的唯一 ID 的列表。当用户尝试插入时,为他们保留一个唯一 ID,当用户按下保存时,他们现在将占位符替换为他们的数据。

            PS:很难确认这一点,但请注意您所提议的内容存在以下并发问题(有或没有线程):用户 A,开始添加,用户 B 开始添加,用户 A 计算 ID 1234 为最大空闲 ID,用户 B 计算 ID 1234 作为最大空闲 ID。用户 A 插入 ID 1234,用户 B 插入 ID 1234 = Boom!

            【讨论】:

            • 是的,我也想过这个问题,但是命中该文件的遗留代码也会定期添加新记录。
            猜你喜欢
            • 1970-01-01
            • 2013-07-15
            • 2011-02-09
            • 2011-10-15
            • 2013-09-29
            • 1970-01-01
            • 1970-01-01
            • 2011-11-11
            • 2017-12-27
            相关资源
            最近更新 更多