7

我想IRandomAccessStream在 C# 中实现一个实例(它将返回实时生成的数据)。流实际上不需要可写或可搜索,但我想在ReadAsync方法中返回我自己的数据(实际上是 的一部分IInputStream)。

public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
{
    throw new NotImplementedException("To be done");
}

我的两个主要问题是:

  1. 我如何返回实现的东西IAsyncOperationWithProgress?框架中是否有任何内容可以帮助解决这个问题?
  2. 如何将数据写入缓冲区?IBuffer只有LengthCapacity属性(具体的 Buffer 类也不再提供)。
4

2 回答 2

4

How to Convert byte Array to IRandomAccessStream

I've found this blog article, hopefully this realization of IRandomAccessStream can be a starting point for you.

class MemoryRandomAccessStream : IRandomAccessStream
{
    private Stream m_InternalStream;

    public MemoryRandomAccessStream(Stream stream)
    {
        this.m_InternalStream = stream;
    }

    public MemoryRandomAccessStream(byte[] bytes)
    {
        this.m_InternalStream = new MemoryStream(bytes);
    }

    public IInputStream GetInputStreamAt(ulong position)
    {
        this.m_InternalStream.Seek((long)position, SeekOrigin.Begin);

        return this.m_InternalStream.AsInputStream();
    }

    public IOutputStream GetOutputStreamAt(ulong position)
    {
        this.m_InternalStream.Seek((long)position, SeekOrigin.Begin);

        return this.m_InternalStream.AsOutputStream();
    }

    public ulong Size
    {
        get { return (ulong)this.m_InternalStream.Length; }
        set { this.m_InternalStream.SetLength((long)value); }
    }

    public bool CanRead
    {
        get { return true; }
    }

    public bool CanWrite
    {
        get { return true; }
    }

    public IRandomAccessStream CloneStream()
    {
        throw new NotSupportedException();
    }

    public ulong Position
    {
        get { return (ulong)this.m_InternalStream.Position; }
    }

    public void Seek(ulong position)
    {
        this.m_InternalStream.Seek((long)position, 0);
    }

    public void Dispose()
    {
        this.m_InternalStream.Dispose();
    }

    public Windows.Foundation.IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
    {
        var inputStream = this.GetInputStreamAt(0);
        return inputStream.ReadAsync(buffer, count, options);
    }

    public Windows.Foundation.IAsyncOperation<bool> FlushAsync()
    {
        var outputStream = this.GetOutputStreamAt(0);
        return outputStream.FlushAsync();
    }

    public Windows.Foundation.IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer)
    {
        var outputStream = this.GetOutputStreamAt(0);
        return outputStream.WriteAsync(buffer);
     }
}
于 2012-12-05T13:59:24.627 回答
2
  1. 使用AsyncInfo.Run(Func<CancellationToken, IProgress<uint>, Task<IBuffer>>)方法从委托创建 IAsyncOperationWithProgress 实例。

    public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
    {    
        if (buffer == null) throw new ArgumentNullException("buffer");
    
        Func<CancellationToken, IProgress<uint>, Task<IBuffer>> taskProvider =
        (token, progress) => ReadBytesAsync(buffer, count, token, progress, options);
    
        return AsyncInfo.Run(taskProvider);
    }
    
    private async Task<IBuffer> ReadBytesAsync(IBuffer buffer, uint count, CancellationToken token, IProgress<uint> progress, InputStreamOptions options)
    {
    ... Fill the buffer here. Report the progress.
        return buffer;
    }
    
  2. 通常您不需要直接访问缓冲区数据。但如果您需要在 c# 中执行此操作,您可以使用 System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions 类将数据复制到缓冲区/从缓冲区复制数据。

于 2012-12-05T20:06:59.390 回答