1

Here is how the Code looks.

void ApplyFilter()
{
    this.filterOperationInProgress = true;
    WriteableBitmap wBmp = new WriteableBitmap(0, 0);
    wBmp = LocalWriteableBitmap.Clone();
    NokiaFilters nf = new NokiaFilters(wBmp, FilterName.Mango);
    wBmp = nf.render().Result;
    this.filterOperationInProgress = false;
}

NokiaFilter Class :

class NokiaFilters
{
    WriteableBitmap wb;
    FilterName filtername = FilterName.NoFilter;
    public NokiaFilters(WriteableBitmap wbm1, FilterName filtername1)
    {
        wb = wbm1;
        filtername = filtername1;
    }

    public async Task<WriteableBitmap> render()
    {
        MemoryStream memstream = new MemoryStream(wb.ToByteArray());
        if (memstream == null)
            return wb;
        //Mango
        else if (filtername == FilterName.Mango)
        {
            memstream.Position = 0;
            // Create a source to read the image from PhotoResult stream
            using (var source = new StreamImageSource(memstream))
            {
                // Create effect collection with the source stream
                using (var filters = new FilterEffect(source))
                {
                    // Initialize the filter 
                    ContrastFilter contrastfilter = new ContrastFilter(0.16);
                    HueSaturationFilter saturationfilter = new HueSaturationFilter(-0.01, -0.53);

                    LomoFilter lomofilter = new LomoFilter(0.5, 0.5, LomoVignetting.Low, LomoStyle.Yellow);
                    // Add the filter to the FilterEffect collection
                    filters.Filters = new List<IFilter> { contrastfilter, saturationfilter, lomofilter };

                   // Create a target where the filtered image will be rendered to
                   var target = new WriteableBitmap((int)wb.PixelWidth, (int)wb.PixelHeight);

                   // Create a new renderer which outputs WriteableBitmaps
                   using (var renderer = new WriteableBitmapRenderer( filters,target))
                   {
                       // Render the image with the filter(s)
                       try
                       {
                           target  = await renderer.RenderAsync().AsTask().ConfigureAwait(false);                                                            
                       }
                       catch (System.InvalidOperationException inv)
                       { }
                       catch { }

                       // Set the output image to Image control as a source
                       return target;
                   }
               }
           }
       }

       return wb;
   }
}

My UI completely stucks and even the back button not responding. When i stop the debugger, the code is pointed at

wBmp = nf.render().Result;

The statement that started executing just before this happens is

target  = await renderer.RenderAsync().AsTask().ConfigureAwait(false);

I am new to parallel programming. I have searched a lot and found that deadlock is very common in such scenario. I believe this is also a Deadlock situation. How can i resolve this?

Update:

After replacing

wBmp = nf.render().Result;

with

wBmp = await nf.render().ConfigureAwait(false);

i am getting HRESULT: 0x8004C00F error in catch {} after

target  = await renderer.RenderAsync().AsTask().ConfigureAwait(false);

Here is the stacktrace:

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Nokia.Graphics.Imaging.WriteableBitmapRenderer.<<RenderAsync>b__0>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at SomeApp.NokiaFilters.<render>d__f.MoveNext()
David Božjak
  • 16,887
  • 18
  • 67
  • 98
Rishabh876
  • 3,010
  • 2
  • 20
  • 37
  • 1
    `render()` is async so you'd better `await` its outcome. – H H Jul 22 '14 at 11:59
  • @HenkHolterman When i use await, the catch { } caught this exception HRESULT: 0x8004C00F. I found nothing substantial on the internet about it. Updating post with stacktrace. – Rishabh876 Jul 22 '14 at 12:17

2 Answers2

1

Solved it.

replaced

MemoryStream memstream = new MemoryStream(wb.ToByteArray());

with

MemoryStream memstream = new MemoryStream(); wb.SaveJpeg(memstream, wb.PixelWidth, wb.PixelHeight, 0, 100);

Rishabh876
  • 3,010
  • 2
  • 20
  • 37
0

Did you try awaiting without ConfigureAwait(false); ? Is this.filterOperationInProgress bounded to UI ? If so there might be a case that you're "changing UI" not on UI thread.

edit: Is wb valid - is PixelWidth and PixelHeight bigger or equal to image which is stored in MemoryStream ?

fex
  • 3,488
  • 5
  • 30
  • 46
  • I tried without `ConfigureAwait(false);` but still no change and `this.filterOperationInProgress` is not bound to UI but i am setting `wBmp` as a source of some Control in the same function. sorry for not including that. – Rishabh876 Jul 22 '14 at 12:40
  • wb has 186624 pixel array length (int) and memorystream has 746496 (byte) length. – Rishabh876 Jul 22 '14 at 12:50
  • I think I know what's wrong - you use source - StreamImageSource while MemoryStream contains WriteableBitmap pixel data - it's not image file data. Try to change it to: "var source = new BitmapImageSource(wb.AsBitmap())" – fex Jul 22 '14 at 13:08
  • I think that am storing something incorrect in memorystream. `MemoryStream memstream = new MemoryStream(wb.ToByteArray());` may be a wrong way to store the image in memstream – Rishabh876 Jul 23 '14 at 04:29