question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DataObject.SetAudio should be exposed with a new overload taking Span<byte>

See original GitHub issue

The DataObject class currently exposes two audio overloads. The first one taking a byte[] calls the second who takes a Stream.

Rationale

Since the introduction of Span<T> it become preferable exposing APIs using Span<T> because they are stack-only types minimizing the use of the garbage collector and easily allows slicing the referenced memory.

Proposed API

namespace System.Windows.Forms
{
    public partial class DataObject : IDataObject
    {
        // Existing methods
        public virtual void SetAudio(byte[] audioBytes);
        public virtual void SetAudio(Stream audioStream);

        // Proposed method
        public virtual void SetAudio(Span<byte> audioBytes);
    }
}

An additional advantage of Span<T> is that it self describes the contiguous memory to be processed from the API. The existing overload taking byte[] does not even allow to specify an offset and length of the array.

Since the current overloads allow specifying an empty interval and only check whether the parameter (byte[] or Stream is null), it is also possible to avoid any parameter check since Span<T> is a ref struct and cannot be null. The parameter Span<byte> can be empty, as it is for the other overloads.

Implementation

The proposed implementation of the new public API is the following:

public virtual void SetAudio(Span<byte> audioBytes)
{
    var stream = new MemoryStream(audioBytes.Length);
    stream.Write(audioBytes);
    stream.Seek(0, SeekOrigin.Begin);
    SetAudio(stream);
}

The MemoryStream is not disposed as it is not directly consumed from the called methods. The other overload does the same.

The PR for this new API is available and contains also a test with four different types of blobs, including an empty one.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:14 (14 by maintainers)

github_iconTop GitHub Comments

4reactions
terrajobstcommented, Oct 4, 2019

Video

We aren’t experts on IDataObject but what is the benefit of using Span<T> here? The Stream API allows you to slice the data already, and it seems the implementation pushes the state into the heap.

For this scenario Span<T> doesn’t make sense; at the very minimum it would need to be Memory<T> (because Span<T> cannot be stored on the heap). However, this seems to complicate the API surface more than it helps.

If slicing the array would be common, I suggest we instead add an overload that simply accepts two ints, or an ArraySegment<T>.

4reactions
karelzcommented, Dec 9, 2018

Thanks @raffaeler - this is helpful for context! cc @zsd4yr @JeremyKuhne

Read more comments on GitHub >

github_iconTop Results From Across the Web

C# - All About Span: Exploring a New .NET Mainstay
You'd likely expose a method that takes a string and provide an implementation that operates on strings. But what if you wanted to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found