C# 中的带宽限制

2024-03-09

我正在开发一个程序,该程序在后台不断发送数据流,我希望允许用户设置上传和下载限制的上限。

我已经阅读了令牌桶 http://en.wikipedia.org/wiki/Token_bucket and 漏桶 http://en.wikipedia.org/wiki/Leaky_bucket算法,似乎后者似乎符合描述,因为这不是最大化网络带宽的问题,而是尽可能不引人注目的问题。

然而,我有点不确定如何实现这一点。一种自然的方法是扩展抽象 Stream 类,以简化现有流量的扩展,但这是否不需要额外的线程来发送数据,同时接收数据(漏桶)?任何有关执行相同操作的其他实现的提示将不胜感激。

另外,虽然我可以修改程序接收的数据量,但带宽限制在 C# 级别的效果如何?计算机是否仍然会接收数据并简单地保存它,从而有效地取消限制效果,还是会等到我要求接收更多数据?

编辑:我对限制传入和传出数据感兴趣,我无法控制流的另一端。


基于 @0xDEADBEEF 的解决方案,我创建了以下基于 Rx 调度程序的(可测试的)解决方案:

public class ThrottledStream : Stream
{
    private readonly Stream parent;
    private readonly int maxBytesPerSecond;
    private readonly IScheduler scheduler;
    private readonly IStopwatch stopwatch;

    private long processed;

    public ThrottledStream(Stream parent, int maxBytesPerSecond, IScheduler scheduler)
    {
        this.maxBytesPerSecond = maxBytesPerSecond;
        this.parent = parent;
        this.scheduler = scheduler;
        stopwatch = scheduler.StartStopwatch();
        processed = 0;
    }

    public ThrottledStream(Stream parent, int maxBytesPerSecond)
        : this (parent, maxBytesPerSecond, Scheduler.Immediate)
    {
    }

    protected void Throttle(int bytes)
    {
        processed += bytes;
        var targetTime = TimeSpan.FromSeconds((double)processed / maxBytesPerSecond);
        var actualTime = stopwatch.Elapsed;
        var sleep = targetTime - actualTime;
        if (sleep > TimeSpan.Zero)
        {
            using (var waitHandle = new AutoResetEvent(initialState: false))
            {
                scheduler.Sleep(sleep).GetAwaiter().OnCompleted(() => waitHandle.Set());
                waitHandle.WaitOne();
            }
        }
    }

    public override bool CanRead
    {
        get { return parent.CanRead; }
    }

    public override bool CanSeek
    {
        get { return parent.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return parent.CanWrite; }
    }

    public override void Flush()
    {
        parent.Flush();
    }

    public override long Length
    {
        get { return parent.Length; }
    }

    public override long Position
    {
        get
        {
            return parent.Position;
        }
        set
        {
            parent.Position = value;
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        var read = parent.Read(buffer, offset, count);
        Throttle(read);
        return read;
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return parent.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        parent.SetLength(value);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        Throttle(count);
        parent.Write(buffer, offset, count);
    }
}

一些测试只需要几毫秒:

[TestMethod]
public void ShouldThrottleReading()
{
    var content = Enumerable
        .Range(0, 1024 * 1024)
        .Select(_ => (byte)'a')
        .ToArray();
    var scheduler = new TestScheduler();
    var source = new ThrottledStream(new MemoryStream(content), content.Length / 8, scheduler);
    var target = new MemoryStream();

    var t = source.CopyToAsync(target);

    t.Wait(10).Should().BeFalse();
    scheduler.AdvanceTo(TimeSpan.FromSeconds(4).Ticks);
    t.Wait(10).Should().BeFalse();
    scheduler.AdvanceTo(TimeSpan.FromSeconds(8).Ticks - 1);
    t.Wait(10).Should().BeFalse();
    scheduler.AdvanceTo(TimeSpan.FromSeconds(8).Ticks);
    t.Wait(10).Should().BeTrue();
}

[TestMethod]
public void ShouldThrottleWriting()
{
    var content = Enumerable
        .Range(0, 1024 * 1024)
        .Select(_ => (byte)'a')
        .ToArray();
    var scheduler = new TestScheduler();
    var source = new MemoryStream(content);
    var target = new ThrottledStream(new MemoryStream(), content.Length / 8, scheduler);

    var t = source.CopyToAsync(target);

    t.Wait(10).Should().BeFalse();
    scheduler.AdvanceTo(TimeSpan.FromSeconds(4).Ticks);
    t.Wait(10).Should().BeFalse();
    scheduler.AdvanceTo(TimeSpan.FromSeconds(8).Ticks - 1);
    t.Wait(10).Should().BeFalse();
    scheduler.AdvanceTo(TimeSpan.FromSeconds(8).Ticks);
    t.Wait(10).Should().BeTrue();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中的带宽限制 的相关文章

  • DispatcherTimer 未按时执行

    我正在使用 c 中的 DispatchTimer 编写一个时钟应用程序 但由于某些原因 我的时钟似乎时不时地跳过 1 秒 例如 52 秒 gt 54 秒 跳过 53 秒 在我看来 计时器并不是每秒都执行一次 DispatcherTimer
  • SetWindowsHookEx 函数返回 NULL

    我正在研究 DLL 注入 但收到错误如下 挂接进程失败 87 参数不正确 目标进程和dll都是64位的 注入代码为 BOOL HookInjection TCHAR target TCHAR dll name https msdn micr
  • Android NDK C++“wstring”支持

    我有用 C 编写的源代码 lib 现在我想在 Android NDK 项目 NDK 6 中编译并使用相同的源代码 lib 我能够编译大多数 C 文件 除了基于 std wstring 的功能 在 Application mk 中 当我指定时
  • 使用不带参数的 Split() 时,默认分隔符是什么?

    所以我看了看String Split 今天 C 中的方法 我意识到你也可以向它传递零参数 这是我从未考虑过的 使用时默认的分隔符是什么Split 没有任何参数 如果没有值 则为空白 来源自here https msdn microsoft
  • 为什么派生类不使用基类的operator=(赋值运算符)?

    以下是实际问题的简化版本 而不是打电话Base operator int 代码似乎生成了一个临时的Derived对象并复制它 既然函数签名似乎完美匹配 为什么不使用基本赋值运算符 这个简化的示例没有显示任何不良影响 但原始代码在析构函数中有
  • 如何将pdf页面设置设置为打印属性对话框?

    大家好 我想知道如何设置 pdf 页面设置到打印属性对话框 例如 如果我的 PDF 页面设置为横向 则布局会自动显示横向而不是纵向 如果我的 PDF 页面设置为纵向 则布局会自动显示纵向 我在这个主题上做了很多研发 但没有找到任何满意的链接
  • 在运行时设置 DataGridView 上的 DataFormatString?

    是否可以在运行时设置 ASP NET DataGridView 中的列或单元格的 DataFormatString 属性 这应该有效 BoundField priceField grid Columns 0 as BoundField pr
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何使用汇编获取BIOS时间?

    我正在从头开始实现一个小型操作系统 用于教育目的 现在 我想使用汇编来获取 BIOS 时间 我对此进行了很多搜索 但找不到任何代码示例来执行此操作 如果有人可以提供任何参考或代码示例或与此相关的任何内容 我将非常感激 See 时钟中断 1a
  • rand() 播种与 time() 问题

    我很难弄清楚如何使用 rand 并使用 Xcode 用 time 为其播种 我想生成 0 到 1 之间的随机十进制数 该代码为我提供了元素 1 和 2 看似随机的数字 但元素 0 始终在 0 077 左右 有什么想法吗 我的代码是 incl
  • F10键没被抓住

    I have a Windows Form and there overriden ProcessCmdKey However this works with all of the F Keys except for F10 I am tr
  • C 中的模仿函数重写

    具体来说 函数重写能够调用基本重写方法 这有两部分 一个是预编译的库代码 1 另一个是库的用户代码 2 我在这里实现了一个尽可能最小的经典 Person 和 Employee 示例 非常感谢了解 OOP 概念的铁杆 C 开发人员的回应 我正
  • Microsoft.Graph - 如何从具有不同用户名的共享邮箱发送?

    我目前正在将使用 SMTP 的服务代码移植到 Office 365 通过 SMTP 我可以使用 发件人 字段在来自共享收件箱的邮件上设置不同的用户名 同时保留共享电子邮箱地址 这似乎无法通过 Office 365 运行 其工艺流程为 客户填
  • 如何在 C# 中使用 XmlDsigC14NTransform 类

    我正在尝试使用规范化 xml 节点System Security Cryptography Xml XMLDsigC14nTransformC net Framework 2 0 的类 该实例需要三种不同的输入类型 NodeList Str
  • 如何将字符串转换为 Indian Money 格式?

    我正在尝试将字符串转换为印度货币格式 例如如果输入为 1234567 则输出应为 12 34 567 我编写了以下代码 但它没有给出预期的输出 CultureInfo hindi new CultureInfo hi IN string t
  • asp.net c# 防止在从服务器端代码更改索引时触发 selectedindexchanged 事件

    我在同一个 aspx 页面上有两个下拉列表控件
  • 理解 C++11 中的 std::atomic::compare_exchange_weak()

    bool compare exchange weak T expected T val compare exchange weak 是 C 11 中提供的比较交换原语之一 它是weak即使对象的值等于 它也会返回 falseexpected
  • 有没有更好的方法来获取每个项目与谓词匹配的子序列?

    假设我有一个 IEnumerable 例如 2 1 42 0 9 6 5 3 8 我需要获得与谓词匹配的项目的 运行 例如 如果我的谓词是 bool isSmallerThanSix int number 我想得到以下输出 2 1 0 5
  • 为什么 C# 接口名称前面加上“I”

    这种命名约定背后的基本原理是什么 我没有看到任何好处 额外的前缀只会污染 API 我的想法与康拉德一致response https stackoverflow com a 222502 9898与此相关的question https sta
  • 如何强制执行特定的 UserControl 设计

    我正在编写一个基本用户控件 它将由一堆其他用户控件继承 我需要对所有这些后代控件强制执行某种设计 例如 顶部必须有几个按钮以及一个或两个标签 后代用户控件区域的其余部分可以自由放置任何内容 最初 我认为我可以将一个面板放到 Base Use

随机推荐

  • 如何在 scala 中按 Ordered 参数化 Int

    我有一个具有参数化类型的类 我想对其进行比较运算符 我认为我需要使用 Ordered 特征来实现这一点 但编译器不喜欢我使用它 假设我有以下课程 class Test T lt Ordered T def someOp t T if t l
  • 仅当在构建服务器上运行时单元测试才会失败

    为了帮助单元测试 我们已经完成了DateTime委托中的类 以便DateTime Now可以在单元测试中被覆盖 public static class SystemTime region Static Fields public stati
  • 如何检测我的 Android 应用程序中的广告拦截器?

    有什么方法可以检测广告拦截器何时在应用程序中运行 我想在我的应用程序中检测用户是否使用任何应用程序来阻止应用程序中的广告 如果是 那么我想向用户显示弹出窗口 要求他在使用应用程序时禁用广告拦截器 Android 操作系统没有提供官方方法来以
  • Typescript/babel 导入导致“_1.default 不是函数”

    我正在尝试使用https github com timmywil panzoom https github com timmywil panzoom来自使用 webpack 和 babel 编译的 typescript 项目 问题是打字稿方
  • 自定义树视图

    有没有办法自定义 winform 树视图以获得类似的东西 目的是通过父项目使用一种颜色并定义一个三角形而不是 图标来开发项目 Use TreeViewDrawMode OwnerDrawText所以缩进将由TreeView 除此之外 你应该
  • ::ng-deep 将被弃用 - 有其他选择吗?

    医生说 阴影穿透后代组合器已被弃用 并且主要浏览器和工具正在删除支持 因此 我们计划放弃对 Angular 的支持 对于 deep gt gt gt 和 ng deep 的所有 3 个 在那之前 应该首选 ng deep 以获得与工具更广泛
  • 在 JBoss 上部署 Hibernate 应用程序时出错 - 找不到适用于 jdbc 的驱动程序

    我有一个 Spring Hibernate Web 应用程序 目前在 Tomcat 上运行良好 我正尝试将其部署到 JBoss 7 1 AS 应用程序全部正确启动 但如果我设置 Hibernate Persistence 设置来创建表 则会
  • 如何使用冒号解组 XML 属性?

    我正在使用的一些 SVG XML 文件的属性名称中包含破折号和冒号 例如
  • 如何使用 jasmine 测试 $window.open

    这是我的功能 scope buildForm function majorObjectId name window open FormBuilder Index scope currentAppId form majorObjectId n
  • 如何在 perl 中创建多维数组?

    我这样创建一个多维数组 usr bin perl use warnings use strict my a1 1 2 my a2 a1 3 但事实证明我仍然得到一个一维数组 Perl 中正确的方法是什么 你得到一个一维数组 因为数组 a1在
  • 让 Collections.binarySearch() 与 CompareToIgnoreCase 一起使用?

    因此 我正在一个巨大的 ArrayList 中搜索特定的 String 值 但如果我正在查找的 String 与我传递给的 String 相等 不区分大小写 我需要 Collections binarySearch 返回一个 gt 0 的值
  • 如何使用 jQuery 获取文本输入的所有值?

    我有一个表 其中有一列预先填充的文本输入 table tr td td td td tr table
  • 如何将 zip 文件上传到 azure blob,然后在那里解压缩 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有很多 zip 文件 其中只有几个文件夹和 50 多个文件 如何将这些 zip 文件上传到 azure blob 然后在那里解压缩 将服务
  • mvc c# html.dropdownlist 和 viewbag

    所以我有以下 伪代码 string selectedvalud C List
  • 如何在node.js模块中实现继承?

    我正在编写 Nodejs 应用程序 它基于expressjs 我对在 Nodejs 模块中进行继承感到困惑 我想做的是创建一个模型基类 比方说 my model js module exports function my model my
  • 在 C# 中提取 .cab 文件

    我正在开发一个 C 应用程序 我需要提取一个 cab 文件 我找不到在 C 中执行此操作的库 由于许可问题 我无法使用 Microsoft Deployment Compression Cab dll I found this https
  • 联系表格 7 至 WordPress 用户数据库

    我编写了以下函数 以便在发送联系表单时将其添加到用户数据库字段中 问题是它发送了最终电子邮件 但没有向数据库输入任何内容 因此我一定在某个地方出现错误 任何帮助将不胜感激 add action wpcf7 before send mail
  • 如何向 Spring Security 用户详细信息添加其他详细信息

    我想向用户详细信息添加其他信息 例如用户的 IP 地址 有什么办法可以实现这一点吗 我尝试创建一个新的 CustomSpringUser 类 但问题是如何从 Authentication 对象获取此信息 有没有其他方法来存储经过身份验证的用
  • NSDateFormatter 毫秒错误

    我想创建一个 NSDateFormatter 来解析像这样的日期 2014 05 13 23 31 41 374577 所以 NSDateFormatter formatter NSDateFormatter alloc init form
  • C# 中的带宽限制

    我正在开发一个程序 该程序在后台不断发送数据流 我希望允许用户设置上传和下载限制的上限 我已经阅读了令牌桶 http en wikipedia org wiki Token bucket and 漏桶 http en wikipedia o