-2

Similar but different to this question How do you implement an async action delegate method?

Hi, I have a method that takes two arguments and returns a result, In calculating the result it calls an awaitable function The arguments to the method are only accessible on another thread, so I'm using dispatcher.CheckAccess, dispatcher.Invoke or dispatcher.InvokeAsync. The best result I got so far is something that builds and runs, but the function never got hit even though dispatcher invoke was called.

I found the example in the referenced thread confusing due to the naming T result, whereas I thought T was an in parameter.

my function looks like this:

private async Task<TResult>> fn(object arg1, object arg2){return await x(arg1,arg2);}  

dispatcher code looks something like this:

if (dispatcher.CheckAccess())
result=    await fn(a,b);
else
result=dispatcher.InvokeAsync<TResult>(fn(a,b)); // this is incorrect syntax

Hopefully Stephen Cleary can rescue me :-) I couldn't find an example like this in Concurrency in C# Cookbook. Probably I'm looking at this wrong way?

Thanks Martin

Martin Alley
  • 121
  • 1
  • 9
  • 1
    If you know that your call of `InvokeAsync` is incorrect why not to go to MSDN and know proper syntax? 1) I see no overload of `InvokeAsync` that takes `Func<..., ...>` as an argument; 2) In C# you can't pass method call as an argument. Probably you want to use `InvokeAsync(() => fn(a,b))` – Maxim Jun 17 '17 at 13:35
  • While [mm8's answer](https://stackoverflow.com/a/44631088/263693) will get your code to compile, I generally recommend architecting the code so that background operations do not require the presence of a UI layer. E.g., getting the `TResult` first and *then* starting the background operation. – Stephen Cleary Jun 19 '17 at 20:26

2 Answers2

1

The InvokeAsync method accepts an Action or a Func<T> that you may await:

await Dispatcher.InvokeAsync(async () => await fn(a, b));
mm8
  • 163,881
  • 10
  • 57
  • 88
0

Ok, looking at this with a fresh mind this morning. I went back to the code that ran, but didn't produce results. Turns out the thread associated with the dispatcher was a background thread in state waitsleepjoin. The object I needed was an image. By freezing the image, I found I didn't need to worry about threading issues at all - there was no dispatcher available. Hope this helps someone else. Martin

Martin Alley
  • 121
  • 1
  • 9