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.

Can I use refection method call with UniTask with return value?

See original GitHub issue

Hi,

I am trying to use Reflection call in Unity under WebGL platform runtime. One of the feature required getting the return value from an await-able task. So I have something like this implemented :

namespace AysncTest{
    public class Tester{
        public Tester() {}
        public async UniTask<bool> Guess(int waitTime)
        {
            await UniTask.Delay(TimeSpan.FromSeconds(waitTime));
            var result = waitTime % 2 == 0;
            return result;
        }
    }

    public class Caller {
        public Caller(){}
        //Usage : await caller.InvokeAsync(tester, "Guess", 2);
        public UniTask<object> InvokeAsync(object target, string methodName, params object[] args){
            var method = Tester.GetType().GetMethod(methodName);
            dynamic task = method.Invoke(target, args); //This can only be use in JIT
            return await task;
        }
    }
}

But then I found out the keyword “dynamic” can only be use in JIT, according to an answer by Eric Lippert.

Will there be any other alternative way that I can do this?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:11 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
yudi-xiao-letscozecommented, Jun 7, 2021
var awaitableTask = method.Invoke(targetObject, commandTargetTarget.Command.args);
var taskType = awaitableTask.GetType();
var preserveMethod = taskType.GetMethod("Preserve");
var asUniTaskMethod = taskType.GetMethod("AsUniTask");
var preserveTask = preserveMethod?.Invoke(awaitableTask, null);
var preserveUniTask = (UniTask) asUniTaskMethod?.Invoke(preserveTask, null);
await preserveUniTask;
var getAwaiterMethod = taskType.GetMethod("GetAwaiter");
var awaiter = getAwaiterMethod?.Invoke(preserveTask, null);
var getResultMethod = awaiter?.GetType().GetMethod("GetResult");
var taskResult = getResultMethod?.Invoke(awaiter, null);

Finally get it working, here is my final working code incase anyone have the same problem.

0reactions
yudi-xiao-letscozecommented, Jun 8, 2021

After a lot of try catch, I verified that this bug have nothing to do with UniTask.

I’ve use custom attributes on the function’s return value to identify what is the generic type T of UniTask<T>, but the IL2CPP compiler must have strip that away.

So I now replace this approach with checking methodInfo.ReturnType.ContainsGenericParameters and getting its Type via methodInfo.ReturnType.GenericTypeArguments.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Awaiting a reflected method where the return type is only ...
Yes, if I do that with a reference type as the return - Task<SomeClass> it compiles but crashes at runtime. Convert. ChangeType <--...
Read more >
Asynchronous function in Unity. Async and await keyword
Since Unity 2019, Unity introduces C# task and async/await keyword to MonoBehaviour. For Unity callback functions like Start, Update, ...
Read more >
Feedback - Task preemption
I figure that this is possible with reflection (I've analyzed `SynchronizationContext` inputs and the generated state machines with a debugger), ...
Read more >
ArgumentException: method return type is incompatible
I'm sending an integer via a UI button event in 4.6 to this (simplified) function and it's giving me a runtime error.
Read more >
Getting data from any API using UnityWebRequest with UniTask
With UniTask, you can write clean and efficient code for your games that is ... of UniTask and show you how to use...
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