2012-12-05 21 views
7

Ich möchte eine Instanz von IRandomAccessStream in C# implementieren (es wird in Echtzeit erzeugte Daten zurückgeben). Der Stream muss nicht tatsächlich beschreibbar oder suchbar sein, aber ich möchte meine eigenen Daten in der ReadAsync-Methode (die tatsächlich Teil von IInputStream ist) zurückgeben.Wie kann ich IRandomAccessStream in C# implementieren?

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

Meine zwei Hauptfragen sind:

  1. wie kann ich etwas zurückgeben, die IAsyncOperationWithProgress implementiert? Ist etwas in den Rahmen eingebaut, um dabei zu helfen?
  2. Wie schreibe ich Daten in den Puffer? IBuffer hat nur Length und Capacity Eigenschaften (die konkrete Buffer-Klasse bietet auch keine mehr).
+0

Duplizieren von http://stackoverflow.com/questions/10112696/how-to-implement-iasyncoperatingwithprogress? –

+0

@ RenéWolferink Ich habe diese Frage gesehen, aber die Antwort dort spricht mein Problem nicht wirklich an. –

Antwort

4

How to Convert byte Array to IRandomAccessStream

ich diesen Blog-Artikel gefunden haben, hoffentlich diese Erkenntnis von IRandomAccessStream für Sie ein Ausgangspunkt sein.

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. Verwenden AsyncInfo.Run(Func<CancellationToken, IProgress<uint>, Task<IBuffer>>) Methode IAsyncOperationWithProgress weise aus einem Delegierten zu schaffen.

    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. Normalerweise müssen Sie nicht direkt auf die Pufferdaten zugreifen. Wenn Sie dies jedoch in C# tun müssen, können Sie die System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions-Klasse verwenden, um Daten in/aus einem Puffer zu kopieren.

+0

Können Sie das bitte mehr erklären? – durron597

+0

Ich habe meine Antwort mit mehr Details aktualisiert. –

+0

danke, sieht so aus, beantwortet den ersten Teil meiner Frage. Noch keine Idee, wie ich einen IBuffer füllen, obwohl –

Verwandte Themen