【问题标题】:How can I have an operation timeout in Portable Class Libraries?如何在可移植类库中设置操作超时?
【发布时间】:2013-06-11 18:42:42
【问题描述】:

我有一个针对所有内容的可移植类库。因此,没有任务或异步支持。这非常痛苦。

所以,我正在尝试实现一个通用扩展方法,以便操作可以超时。这是我目前所拥有的:

    public static bool WithTimeout(Action task, int duration)
    {
        bool complete=false;
        ThreadPool.QueueUserWorkItem((o) =>
            {
                task();
                complete = true;
            });
        int timeout = 0;
        while (!complete)
        {
            new ManualResetEvent(false).WaitOne(1);
            timeout++;
            if (timeout > duration)
            {
                return false;
            }
        }
        return true;
    }

这似乎很可能是错误的,而且非常丑陋。有没有更好的办法?

【问题讨论】:

  • 您的代码存在一些可移植性问题 :) 在某些目标上,它永远不会看到“已完成”布尔值变为 true。需要将其声明为 volatile。而且您几乎永远不会等待 1 毫秒。简单地省略 timeout 并将 duration 传递给 WaitOne() 就是解决方案。让代码运行超过超时、完全未被观察到并且可能永远阻塞是非常丑陋的。
  • @HansPassant 问题在于,如果这个过程更快完成,我希望它尽快返回,如果不需要则不要等待整个超时
  • 正确使用MRE,在线程中调用Set()而不是使用bool。
  • @HansPassant 噢噢噢噢。刚刚点击。永远不必在其他任何地方使用这些东西。我讨厌可移植类库中公开的这种超级严格的功能集

标签: c# .net timeout portable-class-library


【解决方案1】:

@Hans 说要正确使用 ManualResetEvent。这样做之后,我得到了这个(好多了)代码:

    public static bool WithTimeout(Action task, int duration)
    {
        var e=new ManualResetEvent(false);
        ThreadPool.QueueUserWorkItem((o) =>
            {
                task();
                e.Set();
            });
        return e.WaitOne(duration);
    }

【讨论】:

  • 对你的 stackoverflow 答案进行编辑会暴露你实际代码库中的错误的尴尬时刻
【解决方案2】:

如果您需要异步和任务支持,我强烈建议您查看 Microsoft BCL 库。它与便携式类库兼容。

只需使用 nuget 搜索即可。

http://nuget.org/packages/Microsoft.Bcl.Async/

【讨论】:

  • 我想要,但我不能包含任何外部依赖项:/
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多