Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有流大小而不是流数量的缓冲区# 我有一个Producer() 在Consumer()中,我使用System.Reactive(4.1.2)订阅了阻塞集合作为可观察 我使用的是缓冲区,但只能缓冲大量的流_C#_System.reactive - Fatal编程技术网

C# 具有流大小而不是流数量的缓冲区# 我有一个Producer() 在Consumer()中,我使用System.Reactive(4.1.2)订阅了阻塞集合作为可观察 我使用的是缓冲区,但只能缓冲大量的流

C# 具有流大小而不是流数量的缓冲区# 我有一个Producer() 在Consumer()中,我使用System.Reactive(4.1.2)订阅了阻塞集合作为可观察 我使用的是缓冲区,但只能缓冲大量的流,c#,system.reactive,C#,System.reactive,问题-我可以使用buffer运算符处理流的大小而不是流的数量吗 当缓冲区大小交叉时(例如1024KB或1MB),创建新的缓冲区? class Program { private static readonly BlockingCollection<Message> MessagesBlockingCollection = new BlockingCollection<Message>(); private static void

问题-我可以使用
buffer
运算符处理流的大小而不是流的数量吗

当缓冲区大小交叉时(例如1024KB或1MB),创建新的缓冲区?

    class Program
    {
        private static readonly BlockingCollection<Message> MessagesBlockingCollection = new BlockingCollection<Message>();

    private static void Producer()
    {
        int ctr = 1;
        while (ctr <= 11)
        {
            MessagesBlockingCollection.Add(new Message { Id = ctr, Name = $"Name-{ctr}" });
            Thread.Sleep(1000);
            ctr++;
        }
    }

    private static void Consumer()
    {
        var observable = MessagesBlockingCollection.GetConsumingEnumerable().ToObservable();

        var bufferedNumberStream = observable.BufferWithThrottle(TimeSpan.FromSeconds(60), 5)
                                    .Subscribe(ts =>
                                    {
                                        WriteToFile(ts.ToList());
                                    });
    }

    private static void WriteToFile(List<Message> listToWrite)
    {
        using (StreamWriter outFile = System.IO.File.CreateText(Path.Combine(@"C:\TEMP", $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json")))
        {
            outFile.Write(JsonConvert.SerializeObject(listToWrite));
        }
    }

    static void Main(string[] args)
    {
        var producer = Task.Factory.StartNew(() => Producer());
        var consumer = Task.Factory.StartNew(() => Consumer());
        Console.Read();
     }
    }
类程序
{
私有静态只读BlockingCollection消息BlockingCollection=新建BlockingCollection();
私有静态无效生成器()
{
int ctr=1;
while(ctr)
{
WriteToFile(ts.ToList());
});
}
私有静态无效写入文件(列表列表写入)
{
使用(StreamWriter outFile=System.IO.File.CreateText(Path.Combine(@“C:\TEMP”,$”{DateTime.Now.ToString(“yyyymmddhhmmssff”)}.json”))
{
Write(JsonConvert.SerializeObject(listToWrite));
}
}
静态void Main(字符串[]参数)
{
var producer=Task.Factory.StartNew(()=>producer());
var consumer=Task.Factory.StartNew(()=>consumer());
Console.Read();
}
}
可观测延拓法

public static IObservable<IList<TSource>> BufferWithThrottle<TSource>(this IObservable<TSource> source,
                                                                            TimeSpan threshold, int noOfStream)
    {
        return Observable.Create<IList<TSource>>((obs) =>
        {
            return source.GroupByUntil(_ => true,
                                       g => g.Throttle(threshold).Select(_ => Unit.Default)
                                             .Merge(g.Buffer(noOfStream).Select(_ => Unit.Default)))
                         .SelectMany(i => i.ToList())
                         .Subscribe(obs);
        });
    }
public static IObservable BufferWithThrottle(此IObservable源,
时间跨度阈值,int noOfStream)
{
返回可观察。创建((obs)=>
{
返回source.GroupByUntil(=>true,
g=>g.Throttle(阈值)。选择(=>Unit.Default)
.Merge(g.Buffer(noOfStream).Select(=>Unit.Default)))
.SelectMany(i=>i.ToList())
.认购(obs);
});
}

很高兴看到扩展方法在使用:)

您可以稍微修改它,使其
扫描
消息的运行计数
大小。这样我们就失去了类型泛型

public class Message
{
    public string Payload { get; set; }
    public int Size { get; set; }
}

public static IObservable<IList<Message>> BufferWithThrottle(this IObservable<Message> source,
                                                     TimeSpan threshold, int maxSize)
{
    return Observable.Create<IList<Message>>((obs) =>
    {
        return source.GroupByUntil(_ => true,
                                   g => g.Throttle(threshold).Select(_ => Unit.Default)
                                         .Merge(g.Select( i => i.Size)
                                                 .Scan(0, (a, b) => a + b)
                                                 .Where(a => a >= maxSize)
                                                 .Select(_ => Unit.Default)))
                     .SelectMany(i => i.ToList())
                     .Subscribe(obs);
    });
}
公共类消息
{
公共字符串有效负载{get;set;}
公共整数大小{get;set;}
}
公共静态IObservable BufferWithThrottle(此IObservable源,
时间跨度阈值,int maxSize)
{
返回可观察。创建((obs)=>
{
返回source.GroupByUntil(=>true,
g=>g.Throttle(阈值)。选择(=>Unit.Default)
.Merge(g.Select(i=>i.Size)
.扫描(0,(a,b)=>a+b)
。其中(a=>a>=maxSize)
.Select(=>Unit.Default)))
.SelectMany(i=>i.ToList())
.认购(obs);
});
}

谢谢:),但是如何计算消息大小呢?我又写了一个类'BatchMessage
,我在计算消息大小,
公共类BatchMessage{public message message{get;set;}public int Size{get;set;}public BatchMessage(message message){this.Message=Message;var msg=Newtonsoft.Json.JsonConvert.SerializeObject(Message);this.Size=msg.Length+1;}}}}`然后使用扩展名
IObservable
Yep,这大致就是获得Json字符串大小(或字符长度)的方式。虽然它与写入磁盘的文件保留的字节数不同。@Enigmativity,请重新打开此问题,我将删除另一个问题。谢谢!