2012-12-05 3 views
7

Я хотел бы реализовать экземпляр IRandomAccessStream в C# (он будет возвращать данные, сгенерированные в реальном времени). Поток фактически не должен быть доступен для записи или поиска, но я хочу вернуть свои данные в методе ReadAsync (который фактически является частью IInputStream).Как реализовать IRandomAccessStream в C#?

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

Мои два основных вопроса:

  1. , как я могу вернуть то, что реализует IAsyncOperationWithProgress? Есть ли что-то, встроенное в рамки, чтобы помочь с этим?
  2. Как написать данные в буфер? IBuffer имеет только Length и Capacity свойства (конкретный класс буфера также не предлагается).
+0

Дубликат http://stackoverflow.com/questions/10112696/how-to-implement-iasyncoperationwithprogress? –

+0

@ RenéWolferink Я видел этот вопрос, но ответ там действительно не затрагивает мою проблему. –

ответ

4

How to Convert byte Array to IRandomAccessStream

Я нашел статью блога, надеюсь, это реализация IRandomAccessStream может стать отправной точкой для вас.

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); 
    } 
} 
1
  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 для копирования данных в буфер из буфера.

+0

Можете ли вы объяснить это больше, пожалуйста? – durron597

+0

Я обновил свой ответ более подробно. –

+0

спасибо, похоже, отвечает на первую часть моего вопроса. По-прежнему не знаю, как я заполняю IBuffer, но –

Смежные вопросы