gpt4 book ai didi

c# - WAITFOR RECEIVE 结果偏移/延迟 1 个结果

转载 作者:行者123 更新时间:2023-11-30 17:03:17 27 4
gpt4 key购买 nike

我正在使用 SQL 服务代理。一个连接使用 XML 消息在队列上发送消息。我有一个独立连接,它是 WAITFOR (RECEIVE TOP (1) ...), TIMEOUT 5000。这将进入一个 WHILE (1=1) 循环,在单个 Management Studio 查询中或使用循环 reader.NextResult() 执行单个 ADO.NET SQL 命令。

所有这些似乎都配置正确,因为我最终得到了我期望的每一个结果。

但问题是最近的结果总是被拖延!

假设它一直在运行并且没有 SEND,所以它会一直超时,每 5 秒向控制台打印一次“None”。

好吧,现在我从 SQL Management Studio 查询中SENDSEND 命令立即成功完成。在正常超时间隔之前,我立即在控制台中看到“无”。然后在下一个超时间隔,出现我的“更新”事件!

如果我在一连串“None”之后SEND 两条消息,那么我会立即收到“None”,然后是一条“Update”。同样,在 下一个 超时间隔,将出现第二个“更新”。

我可以SEND 十条消息并立即收到一条“无”和九条“更新”。然后我等待五秒超时并获得最终的“更新”。

所有 SEND 都在同一个对话中,我永远不会结束对话。我不保留。

如果我在 RECEIVE 循环运行时对队列进行脏读,队列总是空的。如果我停止 RECEIVE 循环,它就会填满。如果我从另一个 Management Studio 查询窗口接收到信息,则额外的线索是当我停止查询时,最终输出总是出现。这两个事实让我认为队列正在立即出队,但有些东西锁定在读者端(但是什么??)。

起初我认为这只是我之前看到的 Management Studio 的一种奇怪行为,其中 PRINT(?) 有时会延迟。但我不希望在 ADO.NET 中出现相同的行为

也许它与 SSB 无关,只是 WAITFOR 或者只是多个 ResultSet 的流。我会调查这些选项,但我希望有人能同时认识到这一点。

这些症状你熟悉吗?

谢谢!

  • 有什么方法可以让结果在下一次阻塞操作之前刷新到连接中吗?结果/结果集交付是否延迟?
  • SEND 之后我没有看到任何额外的 sp_lock 结果锁定(也没有)

@Rikalous,这里是 ADO.NET

using (var cmd = connection.CreateCommand())
{
cmd.CommandTimeout = 0;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "upWaitForReceive";

using (var reader = cmd.ExecuteReader())
{
do
{
while (reader.Read()) // Individual messages received
{
string eventType = reader["EventType"] as string;

// do something with the message
}
} while (reader.NextResult()); // next batch
}
}

sql循环是:

SELECT 'Initialized' AS EventType

WHILE (1=1) BEGIN
;DECLARE
@ConversationHandle UNIQUEIDENTIFIER,
@MessageTypeName SYSNAME,
@MessageBody XML

;WAITFOR(
RECEIVE TOP (1) @ConversationHandle = conversation_handle, @MessageTypeName = message_type_name, @MessageBody = message_body
FROM [dbo].[{0}_EventsQueue]
), TIMEOUT 5000

IF (@@ROWCOUNT = 0) BEGIN
SELECT 'None' AS EventType; -- Allow the blocking call to spin anyway
CONTINUE;
END

IF (@MessageTypeName = ...) BEGIN
SELECT ...
END ELSE IF (@MessageTypeName = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog') BEGIN
END CONVERSATION @ConversationHandle
SELECT @Message = 'Conversation Terminated' -- Not Expected
RAISERROR (@Message, 11, 1)
RETURN
END
END

;END CONVERSATION @ConversationHandle -- This will never be reached. But if it were, this is what should be done

最佳答案

我相信 RAISERROR (...) WITH NOWAIT 应该刷新缓冲区,但我已经有一段时间没有使用它了。

关于c# - WAITFOR RECEIVE 结果偏移/延迟 1 个结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18777816/

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