IRandomAccessStreams & Streams

Bij het ontwikkelen van Windows Store Apps met C# en Xaml heb je rekening te houden met twee werelden, enerzijds .Net, anderzijds WinRT. Dit zie je op hele veel terreinen terug. Async operaties binnen .Net geven vaak een Task terug, WinRT apis geven een IAsyncOperation terug, binnen .net heb je Stream en in WinRT zijn het IInputStream of IOutputStream. Deze verschillen worden vaak via extension methods

 

Via extension methods worden deze verschillen overbrugt. Hier als voorbeeld van Task naar IAsyncResult:

Task.Run(() => { }).AsAsyncAction();

En in streams kan je het volgende gebruiken: 

Stream s = GetStream();
IInputStream inputStream = s.AsInputStream();
IOutputStream outputStream = s.AsOutputStream();

En ook andersom, dus vanuit WinRT naar .Net types zijn er extension methods beschikbaar:

Stream s1 = inputStream.AsStreamForRead();
Stream s2 = outputStream.AsStreamForWrite();

Echter zijn er ook een flink aantal API's die een IRandomAccessStream verwachten, zoals bijvoorbeeld SetSource method van een Bitmap. Hier heb ik in de API nog geen out-of-the-box oplossing voor gevonden. Gelukkig is een wrapper maken over een memorystream heen die deze interface implementeerd niet heel ingewikkeld:

public class StreamRandomAccessStream : IRandomAccessStream
        {
            private MemoryStream _stream;

            public StreamRandomAccessStream(MemoryStream stream)
            {
                _stream = stream;
            }

            public bool CanRead
            {
                get { return _stream.CanRead; }
            }

            public bool CanWrite
            {
                get { return _stream.CanWrite; }
            }

            public IRandomAccessStream CloneStream()
            {
                var memoryStream = new MemoryStream();
                _stream.CopyTo(memoryStream);
                return new StreamRandomAccessStream(memoryStream);
            }

            public IInputStream GetInputStreamAt(ulong position)
            {
                _stream.Position = (long)position;
                return _stream.AsInputStream();
            }

            public IOutputStream GetOutputStreamAt(ulong position)
            {
                _stream.Position = (long)position;
                return _stream.AsOutputStream();
            }

            public ulong Position
            {
                get { return (ulong)_stream.Position; }
            }

            public void Seek(ulong position)
            {
                _stream.Seek((long)position, SeekOrigin.Begin);
            }

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

            public void Dispose()
            {
                _stream.Dispose();
            }

            public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
            {
                return _stream.AsInputStream().ReadAsync(buffer, count, options);
            }

            public IAsyncOperation<bool> FlushAsync()
            {
                return _stream.AsOutputStream().FlushAsync();
            }

            public IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer)
            {
                return _stream.AsOutputStream().WriteAsync(buffer);
            }
  •   RT @VisualStudio: In this episode, we're joined by Kasey Uhlenhuth (@kuhlenhuth) who shows some of the refactoring features available in Vi…
  •   @VSTS problems with build queues atm?
  •   RT @donasarkar: Hi #WindowsInsiders we have released Build 17713 to the Fast ring! This build has several new features we think IT Pros wil…
  •   RT @maryjofoley: ICYMI, another Windows 10 on ARM PC is available: Lenovo Miix 630 ARM-based 2-in-1 Windows tablet goes on sale for $900 ht…
  •   the moment you have a meeting and skype for business protocol handller is lost again ...
  •   @LocalJoost Surface Go vanaf 27 augustus te bestellen?
  •   tnx @VistaHypotheken https://t.co/qFoQS6mQ63
  •   @gotheap based on the link i understand they should show up after a build as well? i only see them for the test on… https://t.co/XadwWJjIAM
  •   @panos_panay will the surface go with lte have gps? i need a new device to run my own app for navigation while flying around
  •   @aaronbjork @IoannisKarlis @Jira @VSTS and replace delivery plans with the feature timeline extension. that is really helpful!