简体   繁体   中英

Plugin - Using Task class in .Net 4.0 workaround

I'm writing a plugin for in-app purchases for my unity game which needs to use the .Net 3.5 framework.

So going from the docs ref: unity WP8 plugin-docs

It states: "...implement identical non-private methods/fields/properties as in the real DLL"

So I'm trying to apply that to the following method, which needs to use the Task class as it awaits a method.

So here's the method that actually does the work.

public async Task<bool> PurchaseUpgrade(string ID)
{
    var listings = await CurrentApp.LoadListingInformationAsync();

     //The rest of the method-body is irrelevant... 
       So this won't compile as-is.
}

So yeah I need to write a method in the dll the editor 'uses' just with a matching signature, alas I can't because of the Task class.

public async Task<bool> PurchaseUpgrade(string ID)
{
    //This could literally be empty if the method was void, but need it to return
      Task<bool>, and can't work out how

    return true;
}

Anyone able to give any insight into how I can accomplish this?

Thanks in advance

You should be able to use the Task.FromResult<T>() method.

return Task.FromResult(true);

Or if you can't use .NET 4.5, try this:

return Task.Factory.Start(() => true);

I found the answer to this is encapsulation. The async methods need to be private and have public methods call them.

In the dll that targets .Net 4.0 or greater you have your async method like so:

 private async void Foo()
 {
     await LongRunningMethod();
 }

 public void Bar()
 {
    //Call the async method
    Foo();
 }

Now to use the dll above in Unity, you have to create a dll that targets .Net 3.5 as stated above, and have it include any method, along with matching signature that you wish to use from within a unity script.

So in the .Net 3.5 dll you just need to:

public void Bar()
{
    //This can literally be empty if you want
}

And that's it...almost

The assembly names and default namespace properties of both dll's have to match.

The .Net 3.5 dll needs to be placed in the folder

 /Assets/Plugins

And the .Net 4.0 dll needs to be placedin the folder

 /Assets/Plugins/WP8

This way, you won't get any compilation errors when working in the unity editor, the method calls from the .Net 3.5 dll will be called. When you're running on a WP8 device however the .Net 4.0 with the real 'magic' inside will be called.

Hope that helps anyone out there.

Note: As stated in the comments below it's worth mentioning that you won't be able to catch an exception thrown by a Async void method.

You might think this catches exceptions thrown by the async void method:

 public void CallAsyncMethod()
 {

        try
        {
              Foo(); //The async void mentioned above
        }
        catch(Exception)
        {
              //But it doesn't
        }

 }

To be able to write 'safe' code using an async void method you need to add the exception handling inside the async void method, like so:

 private async void Foo()
 {

        try
        {
              await LongRunningMethod();
        }
        catch(Exception)
        {
              //This is now safe, the exception will be caught, although admittedly  
              // ugly code, better to have it in the called IMO.
        }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM