2012-12-05 16 views
7

Vorrei implementare un'istanza di IRandomAccessStream in C# (restituirà i dati generati in tempo reale). Lo streaming non ha realmente bisogno di essere scrivibile o ricercabile, ma voglio restituire i miei dati nel metodo ReadAsync (che è in realtà parte di IInputStream).Come posso implementare IRandomAccessStream in C#?

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

Le mie due domande principali sono:

  1. Come faccio a restituire qualcosa che implementa IAsyncOperationWithProgress? C'è qualcosa di costruito nel framework per aiutare con questo?
  2. Come si scrivono i dati nel buffer? IBuffer ha solo le proprietà Length e Capacity (anche la classe Buffer concreta non offre più).
+0

Duplicato di http://stackoverflow.com/questions/10112696/how-to-implement-iasyncoperationwithprogress? –

+0

@ RenéWolferink Ho visto questa domanda, ma la risposta non risolve il mio problema. –

risposta

4

How to Convert byte Array to IRandomAccessStream

ho trovato questo articolo del blog, si spera questa realizzazione di IRandomAccessStream può essere un punto di partenza per voi.

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. Usa AsyncInfo.Run(Func<CancellationToken, IProgress<uint>, Task<IBuffer>>) metodo per creare un'istanza IAsyncOperationWithProgress da un delegato.

    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. In genere non è necessario accedere direttamente ai dati del buffer. Ma nel caso in cui sia necessario eseguire questa operazione in C#, è possibile utilizzare System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBuffer Classe di estensioni per copiare i dati su/da un buffer.

+0

Puoi spiegarlo meglio per favore? – durron597

+0

Ho aggiornato la mia risposta con maggiori dettagli. –

+0

grazie, sembra che risponda alla prima parte della mia domanda. Ancora non ho idea di come riempire un IBuffer però –

Problemi correlati