我正在使用 BlockingCollection实现生产者/消费者模式。我有一个异步循环,它用要处理的数据填充集合,然后客户端可以在稍后的时间访问这些数据。数据包很少到达,我希望在不使用阻塞调用的情况下完成轮询。
本质上,我正在寻找类似 BeginTake 的东西和 EndTake阻塞集合中不存在,因此我可以在回调中使用内部线程池。它不一定是 BlockingCollection以任何方式。任何满足我需要的东西都会很棒。
这就是我现在所拥有的。 _bufferedPackets是 BlockingCollection<byte[]> :
public byte[] Read(int timeout)
{
byte[] result;
if (_bufferedPackets.IsCompleted)
{
throw new Exception("Out of packets");
}
_bufferedPackets.TryTake(out result, timeout);
return result;
}
我希望它是这样的,用伪代码:
public void Read(int timeout)
{
_bufferedPackets.BeginTake(result =>
{
var bytes = _bufferedPackets.EndTake(result);
// Process the bytes, or the resuting timeout
}, timeout, _bufferedPackets);
}
我对此有哪些选择?我不想将任何线程置于等待状态,因为它还有很多其他 IO 内容需要处理,而且我很快就会用完线程。
更新:我重写了相关代码以不同方式使用异步过程,本质上是根据超时限制内是否存在等待请求来交换回调。这工作正常,但如果有一种方法可以做到这一点而不诉诸计时器和交换 lambda,那仍然会很棒,因为这可能会导致竞争条件并且难以编写(和理解)。我也用自己的异步队列实现解决了这个问题,但如果有更标准且经过良好测试的选项,它仍然很棒。
最佳答案
我可能误解了你的情况,但你不能使用非阻塞集合吗?
我创建了这个例子来说明:
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncTakeFromBlockingCollection
{
class Program
{
static void Main(string[] args)
{
var queue = new ConcurrentQueue<string>();
var producer1 = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i += 1)
{
queue.Enqueue("=======");
Thread.Sleep(10);
}
});
var producer2 = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i += 1)
{
queue.Enqueue("*******");
Thread.Sleep(3);
}
});
CreateConsumerTask("One ", 3, queue);
CreateConsumerTask("Two ", 4, queue);
CreateConsumerTask("Three", 7, queue);
producer1.Wait();
producer2.Wait();
Console.WriteLine(" Producers Finished");
Console.ReadLine();
}
static void CreateConsumerTask(string taskName, int sleepTime, ConcurrentQueue<string> queue)
{
Task.Factory.StartNew(() =>
{
while (true)
{
string result;
if (queue.TryDequeue(out result))
{
Console.WriteLine(" {0} consumed {1}", taskName, result);
}
Thread.Sleep(sleepTime);
}
});
}
}
}
这是程序的输出
我相信 BlockingCollection 旨在包装并发集合并提供一种允许多个消费者阻塞的机制;等待生产者。这种用法似乎与您的要求相反。
我找到了这个 article about the BlockingCollection class有帮助。
关于c# - 异步取自阻塞集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11949424/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排
我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume
我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用
什么是Linq聚合方法的ruby等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj