C# 记住梦想,等待有东西读

C# 记住梦想,等待有东西读,c#,asynchronous,stream,C#,Asynchronous,Stream,这是一个非常简单的问题,但我似乎无法在没有与某人交谈的情况下解决这个问题 我需要一个类似MemoryStream的流,它将异步阻止读取,直到有东西要读取或超时 更新: 好啊我已经放弃并自己编写了包装器类,但EndRead始终返回0。请看下面的代码。(不要提供面向任务的解决方案。) 尝试类似的方法,这样做只是循环并等待直到有对象被读取 private static readonly MemoryStream _reader; private static object _data;

这是一个非常简单的问题,但我似乎无法在没有与某人交谈的情况下解决这个问题

我需要一个类似MemoryStream的流,它将异步阻止读取,直到有东西要读取或超时

更新: 好啊我已经放弃并自己编写了包装器类,但EndRead始终返回0。请看下面的代码。(不要提供面向任务的解决方案。)


尝试类似的方法,这样做只是循环并等待直到有对象被读取

    private static readonly MemoryStream _reader;
    private static object _data;

    static Program()
    {
        _reader = new MemoryStream();
    }

    private static void Main(string[] args)
    {
        Task.Run(async delegate()
        {
            while (true)
            {
                if (_data == null)
                    await Task.Delay(1000); // so the cpu can have rest
                                            // you can lower the value of this
                else
                {
                    // read here
                    await Task.Delay(1000);
                }
            }
        });
    }

如果我理解正确的话,您需要一个您写入的流,另一个线程从中读取。你可以自己做,即:

public sealed class MyStream : Stream
{
    private readonly MemoryStream underlyingStream = new MemoryStream();
    private readonly AutoResetEvent waitHandle = new AutoResetEvent(false);

    public int Timeout { get; set; }

    public MyStream()
    {
        Timeout = 5000;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        // Write to the stream and notify any waiting threads
        underlyingStream.Write(buffer, offset, count);
        waitHandle.Set();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int bytes;
        while ((bytes = underlyingStream.Read(buffer, offset, count)) == 0)
        {
            // 0 bytes read (end of stream), wait Timeout ms for someone to write
            if (!waitHandle.WaitOne(Timeout))
            {
                throw new TimeoutException();
            }
        }

        return bytes;
    }

    // TODO other mandatory methods
}
我在没有测试的情况下编写了上面的示例,
Stream
的实现是不完整的,它只是为您的解决方案显示了一个可能的方向。如果有多个线程从中读取
,则可能需要大量
超时时间才能完成


如果您不喜欢摆弄等待句柄,还可以在TCP环回上使用套接字,并使用
NetworkStream

上下文不清楚或不明显。它是如何写的?请看C.Evenhuis的代码。这就是我试图避免的代码。如果你真的只想得到一个涉及.NET本身现有实现的答案,我认为你不会得到这个答案。一个简单的启用超时的
Stream
包装器可以在不太麻烦的情况下实现(尽管有当前的答案),但是如果您只对.NET中已经存在的内容感兴趣,那么我想没有必要提供它。谢谢!我已经考虑过实现它,但我希望C#中已经有了一些东西。NetworkStream不好-它需要太多的虚拟可验证项。即使OP愿意接受非内置实现,这个答案也是根本错误的:当
Read()
操作返回0字节时,表示
流的结束。无论您等待多长时间,此时将不会有更多字节。@PeterDuniho我感谢您的评论,您是对的,它应该抛出
TimeoutException
,我将更正我的答案。但我不认为这是根本错误的,我提供了定制解决方案和内置解决方案的想法。
public sealed class MyStream : Stream
{
    private readonly MemoryStream underlyingStream = new MemoryStream();
    private readonly AutoResetEvent waitHandle = new AutoResetEvent(false);

    public int Timeout { get; set; }

    public MyStream()
    {
        Timeout = 5000;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        // Write to the stream and notify any waiting threads
        underlyingStream.Write(buffer, offset, count);
        waitHandle.Set();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int bytes;
        while ((bytes = underlyingStream.Read(buffer, offset, count)) == 0)
        {
            // 0 bytes read (end of stream), wait Timeout ms for someone to write
            if (!waitHandle.WaitOne(Timeout))
            {
                throw new TimeoutException();
            }
        }

        return bytes;
    }

    // TODO other mandatory methods
}