2012-12-05 11 views
7

Chciałbym zaimplementować wystąpienie IRandomAccessStream w języku C# (będzie zwracanie danych generowanych w czasie rzeczywistym). Strumień w rzeczywistości nie musi być zapisywalny lub dostępny, ale chcę zwrócić moje własne dane w metodzie ReadAsync (która jest faktycznie częścią IInputStream).Jak mogę wdrożyć IRandomAccessStream w języku C#?

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

moje dwa główne pytania:

  1. jak mam coś, który implementuje IAsyncOperationWithProgress powrócić? Czy coś jest wbudowane w strukturę, aby pomóc w tym?
  2. Jak zapisać dane w buforze? IBuffer ma tylko właściwości Length i Capacity (klasa konkretnych buforów również nie oferuje żadnej).
+0

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

+0

@ RenéWolferink Widziałem to pytanie, ale odpowiedź tam naprawdę nie rozwiązuje mojego problemu. –

Odpowiedz

4

How to Convert byte Array to IRandomAccessStream

Znalazłem ten wpis na blogu, mam nadzieję, że ta realizacja IRandomAccessStream może być punktem wyjścia dla Ciebie.

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. Zastosowanie AsyncInfo.Run(Func<CancellationToken, IProgress<uint>, Task<IBuffer>>) sposób, aby utworzyć egzemplarz IAsyncOperationWithProgress z pełnomocnika.

    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. Zazwyczaj nie ma potrzeby bezpośredniego dostępu do danych bufora. Ale na wypadek, gdybyś musiał to zrobić w języku C#, możesz użyć klasy System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions, aby skopiować dane do/z bufora.

+0

Czy możesz wyjaśnić to bardziej proszę? – durron597

+0

Zaktualizowałem swoją odpowiedź, podając więcej szczegółów. –

+0

dziękuję, wygląda na to, że odpowiada na pierwszą część mojego pytania. Wciąż nie mam pojęcia, jak mogę wypełnić IBuffer, ale używając –