Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.
Options

Read an image file asynchronously.

Hi all,

I would like to read an image file asynchronously and Im trying to achieve that using async/await from C#. However, I still notice a significant lag with this implementation. Using the profiler I'm pretty confident it is it the FileStream.ReadAsync() method that takes ages to complete and causes the game from updating.

Here's some code.

// Static class for reading the image.
class AsyncImageReader
{
    public static async Task<byte[]> ReadImageAsync(string filePath)
        {
            byte[] imageBytes;
            didFinishReading = false;
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true))
            {
                imageBytes = new byte[fileStream.Length];
                await fileStream.ReadAsync(imageBytes, 0, (int) fileStream.Length);

            }

            didFinishReading = true;

            return imageBytes;
        }
 }

    // Calling function that is called by the OnCapturedPhotoToDisk event.
    public void AddImage(string filePath)
    {
        Task<byte[]> readImageTask = AsyncImageReader.ReadImageAsync(filePath);
        byte [] imageBytes = await readImageTask;
    }

Best Answer

  • Options
    Answer ✓

    For anyone else who stumbled through this dangerous sludge of confusion here's what I ended up with. Not perfect, since I still notice a tracking loss but better than nothing. In the calling function don't use the await keyword, just fire and forget. Let the callback do the work that depends on the read file. This works with any other file type too, I think/hope.

    public static async Task ReadImageBytesAsync(string filepath, Action<byte[]> callback)
    {
        didFinishReading = false;
        byte[] imageBytes;
        using (FileStream sourceStream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize, FileOptions.Asynchronous))
        {
            imageBytes = new byte[sourceStream.Length];
            await sourceStream.ReadAsync(imageBytes, 0, (int) sourceStream.Length);
        }
    
        didFinishReading = true;
    
        callback(imageBytes);
    
    }
    

Answers

  • Options

    First let me ask where is this code running? Unity or a C# directX app? If it's Unity, Unity basically requires all reference classes to be accessed from the main UI thread. Value types can be accessed from background threads. What this means is your app will basically wait regardless of your async/await patterns. You'll need to implement a dispatcher pattern in your Unity class. It if it's C# DX then another note, have you tried chunking your reads? Read in chunks at a time, not the whole file all at once?

    Just some thoughts to help you out.

    Dwight Goins
    CAO & Founder| Independent Architect | Trainer and Consultant | Sr. Enterprise Architect
    MVP | MCT | MCSD | MCPD | SharePoint TS | MS Virtual TS |Windows 8 App Store Developer | Linux Gentoo Geek | Raspberry Pi Owner | Micro .Net Developer | Kinect For Windows Device Developer
    http://dgoins.wordpress.com

  • Options

    @Dwight_Goins_EE_MVP Thanks. Yes it is in Unity. I will have to look up dispatcher pattern to implement this.

    As for anyone else who might come here looking for a quick fix, what I did what hide all the holograms while it's reading so you don't notice the tracking loss/no rendering during that time.

  • Options

    Dwight Goins
    CAO & Founder| Independent Architect | Trainer and Consultant | Sr. Enterprise Architect
    MVP | MCT | MCSD | MCPD | SharePoint TS | MS Virtual TS |Windows 8 App Store Developer | Linux Gentoo Geek | Raspberry Pi Owner | Micro .Net Developer | Kinect For Windows Device Developer
    http://dgoins.wordpress.com

  • Options
    Answer ✓

    For anyone else who stumbled through this dangerous sludge of confusion here's what I ended up with. Not perfect, since I still notice a tracking loss but better than nothing. In the calling function don't use the await keyword, just fire and forget. Let the callback do the work that depends on the read file. This works with any other file type too, I think/hope.

    public static async Task ReadImageBytesAsync(string filepath, Action<byte[]> callback)
    {
        didFinishReading = false;
        byte[] imageBytes;
        using (FileStream sourceStream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize, FileOptions.Asynchronous))
        {
            imageBytes = new byte[sourceStream.Length];
            await sourceStream.ReadAsync(imageBytes, 0, (int) sourceStream.Length);
        }
    
        didFinishReading = true;
    
        callback(imageBytes);
    
    }
    
Sign In or Register to comment.