- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是一只试图学习新技巧的老狗。我非常熟悉一种叫做 PowerBuilder 的语言,在这种语言中,当您想异步执行操作时,您会在新线程中生成一个对象。我要重申:整个对象在单独的线程中实例化并具有不同的执行上下文。该对象上的所有方法都在该单独线程的上下文中执行。
现在,我正在尝试使用 C# 实现一些异步执行,而 .NET 中的线程模型对我来说感觉完全不同。看起来我在一个线程中实例化对象,但我可以指定(在逐个调用的基础上)某些方法在不同的线程中执行。
差异看似微妙,但让我很沮丧。我的老派想法是,“我有一个 helper ,名叫鲍勃。鲍勃出去做事了。”如果我理解正确的话,新派思维是“我是 Bob。如果需要,我有时可以同时揉我的肚子和拍我的头。”
我的真实编码问题:我正在编写一个接口(interface)引擎,它通过 TCP 接收消息,将它们解析为可用数据,然后将该数据放入数据库。 “解析”一条消息大约需要一秒钟。根据解析的数据,数据库操作可能需要不到一秒,也可能需要十秒。 (所有时间都是为了澄清问题。)
我的老派想法告诉我,我的数据库类应该存在于一个单独的线程中,并且有类似 ConcurrentQueue
的东西。 .它只会在该队列上旋转,处理其中可能存在的任何内容。另一方面,解析器需要将消息推送到该队列中。这些消息将是(委托(delegate)?)诸如“根据此对象
中的数据创建订单”或“根据此对象
中的数据更新订单”之类的消息。可能值得注意的是,我实际上想以严格的单线程 FIFO 顺序处理“队列”中的“消息”。
基本上,我的数据库连接不能总是跟上我的解析器。我需要一种方法来确保我的解析器在我的数据库进程试图 catch 时不会减慢速度。有什么建议吗?
-- 编辑:用代码!每个人和每件事都告诉我使用 BlockingCollection
。所以这里有一个简短的最终目标和代码的解释:
这将是一个 Windows 服务。启动时,它将产生多个“环境”,每个“环境”包含一个“dbworker”和一个“接口(interface)”。 “接口(interface)”将有一个“解析器”和一个“监听器”。
class cEnvironment {
private cDBWorker MyDatabase;
private cInterface MyInterface;
public void OnStart () {
MyDatabase = new cDBWorker ();
MyInterface = new cInterface ();
MyInterface.OrderReceived += this.InterfaceOrderReceivedEventHandler;
MyDatabase.OnStart ();
MyInterface.OnStart ();
}
public void OnStop () {
MyInterface.OnStop ();
MyDatabase.OnStop ();
MyInterface.OrderReceived -= this.InterfaceOrderReceivedEventHandler;
}
void InterfaceOrderReceivedEventHandler (object sender, OrderReceivedEventArgs e) {
MyDatabase.OrderQueue.Add (e.Order);
}
}
class cDBWorker {
public BlockingCollection<cOrder> OrderQueue = new BlockingCollection<cOrder> ();
private Task ProcessingTask;
public void OnStart () {
ProcessingTask = Task.Factory.StartNew (() => Process (), TaskCreationOptions.LongRunning);
}
public void OnStop () {
OrderQueue.CompleteAdding ();
ProcessingTask.Wait ();
}
public void Process () {
foreach (cOrder Order in OrderQueue.GetConsumingEnumerable ()) {
switch (Order.OrderType) {
case 1:
SuperFastMethod (Order);
break;
case 2:
ReallySlowMethod (Order);
break;
}
}
}
public void SuperFastMethod (cOrder Order) {
}
public void ReallySlowMethod (cOrder Order) {
}
}
class cInterface {
protected cListener MyListener;
protected cParser MyParser;
public void OnStart () {
MyListener = new cListener ();
MyParser = new cParser ();
MyListener.DataReceived += this.ListenerDataReceivedHandler;
MyListener.OnStart ();
}
public void OnStop () {
MyListener.OnStop ();
MyListener.DataReceived -= this.ListenerDataReceivedHandler;
}
public event OrderReceivedEventHandler OrderReceived;
protected virtual void OnOrderReceived (OrderReceivedEventArgs e) {
if (OrderReceived != null)
OrderReceived (this, e);
}
void ListenerDataReceivedHandler (object sender, DataReceivedEventArgs e) {
foreach (string Message in MyParser.GetMessages (e.RawData)) {
OnOrderReceived (new OrderReceivedEventArgs (MyParser.ParseMessage (Message)));
}
}
它编译。 (发货!)但这是否意味着我做对了?
最佳答案
BlockingCollection使将这种东西放在一起非常容易:
// the queue
private BlockingCollection<Message> MessagesQueue = new BlockingCollection<Message>();
// the consumer
private MessageParser()
{
foreach (var msg in MessagesQueue.GetConsumingEnumerable())
{
var parsedMessage = ParseMessage(msg);
// do something with the parsed message
}
}
// In your main program
// start the consumer
var consumer = Task.Factory.StartNew(() => MessageParser(),
TaskCreationOptions.LongRunning);
// the main loop
while (messageAvailable)
{
var msg = GetMessageFromTcp();
// add it to the queue
MessagesQueue.Add(msg);
}
// done receiving messages
// tell the consumer that no more messages will be added
MessagesQueue.CompleteAdding();
// wait for consumer to finish
consumer.Wait();
消费者在队列上进行非忙碌等待,因此当没有可用资源时它不会占用 CPU 资源。
关于c# - C# 中的线程和异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19847905/
我正在努力做到这一点 在我的操作中从数据库获取对象列表(确定) 在 JSP 上打印(确定) 此列表作为 JSP 中的可编辑表出现。我想修改然后将其提交回同一操作以将其保存在我的数据库中(失败。当我使用
我有以下形式的 Linq to Entities 查询: var x = from a in SomeData where ... some conditions ... select
我有以下查询。 var query = Repository.Query() .Where(p => !p.IsDeleted && p.Article.ArticleSections.Cou
我正在编写一个应用程序包,其中包含一个主类,其中主方法与GUI类分开,GUI类包含一个带有jtabbedpane的jframe,它有两个选项卡,第一个选项卡包含一个jtable,称为jtable1,第
以下代码产生错误 The nested query is not supported. Operation1='Case' Operation2='Collect' 问题是我做错了什么?我该如何解决?
我已经为 HA redis 集群(2 个副本、1 个主节点、3 个哨兵)设置了本地 docker 环境。只有哨兵暴露端口(10021、10022、10023)。 我使用的是 stackexchange
我正在 Desk.com 中构建一个“集成 URL”,它使用 Shopify Liquid 模板过滤器语法。对于开始日期为 7 天前而结束日期为现在的查询,此 URL 需要包含“开始日期”和“结束日期
你一定想过。然而情况却不理想,python中只能使用类似于 i++/i--等操作。 python中的自增操作 下面代码几乎是所有程序员在python中进行自增(减)操作的常用
我需要在每个使用 github 操作的手动构建中显示分支。例如:https://gyazo.com/2131bf83b0df1e2157480e5be842d4fb 我应该显示分支而不是一个。 最佳答
我有一个关于 Perl qr 运算符的问题: #!/usr/bin/perl -w &mysplit("a:b:c", /:/); sub mysplit { my($str, $patt
我已经使用 ArgoUML 创建了一个 ERD(实体关系图),我希望在一个类中创建两个操作,它们都具有 void 返回类型。但是,我只能创建一个返回 void 类型的操作。 例如: 我能够将 book
Github 操作仍处于测试阶段并且很新,但我希望有人可以提供帮助。我认为可以在主分支和拉取请求上运行 github 操作,如下所示: on: pull_request push: b
我正在尝试创建一个 Twilio 工作流来调用电话并记录用户所说的内容。为此,我正在使用 Record,但我不确定要在 action 参数中放置什么。 尽管我知道 Twilio 会发送有关调用该 UR
我不确定这是否可行,但值得一试。我正在使用模板缓冲区来减少使用此算法的延迟渲染器中光体积的过度绘制(当相机位于体积之外时): 使用廉价的着色器,将深度测试设置为 LEQUAL 绘制背面,将它们标记在模
有没有聪明的方法来复制 和 重命名 文件通过 GitHub 操作? 我想将一些自述文件复制到 /docs文件夹(:= 同一个 repo,不是远程的!),它们将根据它们的 frontmatter 重命名
我有一个 .csv 文件,其中第一列包含用户名。它们采用 FirstName LastName 的形式。我想获取 FirstName 并将 LastName 的第一个字符添加到它上面,然后删除空格。然
Sitecore 根据 Sitecore 树中定义的项目名称生成 URL, http://samplewebsite/Pages/Sample Page 但我们的客户有兴趣降低所有 URL(页面/示例
我正在尝试进行一些计算,但是一旦我输入金额,它就会完成。我只是希望通过单击按钮而不是自动发生这种情况。 到目前为止我做了什么: Angular JS - programming-fr
我的公司创建了一种在环境之间移动文件的复杂方法,现在我们希望将某些构建的 JS 文件(已转换和缩小)从一个 github 存储库移动到另一个。使用 github 操作可以实现这一点吗? 最佳答案 最简
在我的代码中,我创建了一个 JSONArray 对象。并向 JSONArray 对象添加了两个 JSONObject。我使用的是 json-simple-1.1.jar。我的代码是 package j
我是一名优秀的程序员,十分优秀!