Git Product home page Git Product logo

unity3dasyncawaitutil's Introduction

unity3dasyncawaitutil's People

Contributors

chronosws avatar jhett12321 avatar svermeulen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unity3dasyncawaitutil's Issues

UnitySynchronizationContext deadlocking?

Seems Unity uses a lock() a delegate/event is invoked which can result in more nightmare bug hunts so it needs to be addressed.

It looks like the lock() is just used for having thread-safe collection access. Use the appropriate System.Collections.Concurrent collection (Queue?) type instead of a lock() statement while still having thread-safe collections.

If exclusive access is required, they might be able to use InterlockedExchange with a Boolean flag that is checked and set thread-safe with the Interlocked helper methods.

The task is to make the WaitForUpdate thread-safe to avoid deadlock situations.

A coworker wrote:

One issue I noticed: await WaitForUpdate() posts to the Unity synchronization context. This shouldn't be a problem, but UnitySynchronizationContext has a major problem in its implementation: it locks the message queue while it's executing messages. This means that if we await WaitForUpdate(), then lock() waiting for some other thread, and that other thread also does await WaitForUpdate(), it'll deadlock because the event queue is locked while the sync context is executing. Bad Unity!

        private void Exec()
        {
            lock (m_AsyncWorkQueue)
            {
                var workCount = m_AsyncWorkQueue.Count;
                for (int i = 0; i < workCount; i++)
                {
                    var work = m_AsyncWorkQueue.Dequeue();
                    work.Invoke();
                }
            }
        }

See the problem there? Rule of thumb: Never call external events or delegates inside of a lock()

Integration problem with Unity WebRTC

Hello everyone!

I am having trouble using await with a method from the Unity WebRTC implementation (I am using version 2.2.0-preview). Most methods which are supposed to be called in a coroutine seem to be working fine, but RTCPeerConnection.CreateAnswer() returns null when I use await.

What I am doing is roughly this:

// WebRTC.Initialize() is already called
// The remoteDescription comes from my signaling server

this.localConnection = new RTCPeerConnection(ref rtcConfig);
await localConnection.SetRemoteDescription(ref remoteDescription);

var answerOptions = new RTCAnswerOptions { iceRestart = false };
var answer = await localConnection.CreateAnswer(ref answerOptions);

// After this answer == null

When I call CreateAnswer() inside a Coroutine, I get a RTCSessionDescription description as expected.

var answerOptions = new RTCAnswerOptions { iceRestart = false };
var answer = localConnection.CreateAnswer(ref answerOptions);

yield return answer;

// After the yield, anser is *not* null and contains a session description in answer.Desc

The return value of RTCPeerConnection.CreateAnswer is a RTCSessionDescriptionAsyncOperation.

Do I need a special Awaiter here that is not covered by IEnumeratorAwaitExtensions?

Any tipps and hints in the right direction would be greatly appreciated!

Thanks in advance for any insights you could provide on this issue and best regards,
Patrick

Should TaskExtensions.AsIEnumerator unwrap AggregateException?

I'm trying to incrementally convert our codebase from coroutines to async/await. Doing it incrementally means a lot of "await " and "Task.AsIEnumerator()" to convert between the two styles at the boundaries.

One issue I've found is that converting a Coroutine -> async Task is not as simple as changing the method from "IEnumerator DoSomethingCoroutine()" -> "async Task DoSomethingAsync()" and fixing up callers to append ".AsIEnumerator()", because exceptions that propagate from Task and AsIEnumerator() are wrapped with AggregateException().

I'm assuming that the main use case of Task.AsIEnumerator is to help with the transition process, so I think there's a good argument for unwrapping the AggregateException. On the other hand, I'm not sure when the AggregateException might contain 2 or more exceptions and what AsIEnumerator should do in that case.

Here's some sample code that illustrates the issue:

    class MyCustomException : Exception {}

    IEnumerator<object> CallerCoroutine() {
        // Old code is sometimes verbose, for call stacks and exception propagation
        using (var cr = DoSomethingCoroutine()) {
            while (true) {
                try {
                    if (!cr.MoveNext()) { break; }
                } catch (MyCustomException e) {
                    // ...
                }
                yield return cr.Current;
            }
        }

        // Simple automated refactor doesn't work because the exception is now AggregateException
        using (var cr = DoSomethingAsync().AsIEnumerator()) {
            // ... body is same as above ...
        }
    }

    IEnumerator<object> DoSomethingCoroutine() {
        if (UnityEngine.Random.value > .5f) { throw new MyCustomException(); }
        yield return null;
    }

    async Task<object> DoSomethingAsync() {
        if (UnityEngine.Random.value > .5f) { throw new MyCustomException(); }
        await Awaiters.NextFrame;
        return null;
    }

Assert hit in UnityAsyncUtil package

We're experiencing the Assert failing in the SimpleCoroutineAwaiter implementation of INotifyCompletion.OnCompleted.

We've also seen this error pop up many times before in random places. This particular part of the code is just waiting on a WaitForUpdate instance.
Unfortunately I don't have any other details, and I've not been able to reproduce this despite many attempts. As far as I can tell the generated task state machine code should only invoke the OnCompleted method once ever, so I really don't understand how this could happen.

The Stacktrace

System.Exception Assert hit in UnityAsyncUtil package!
0 IEnumeratorAwaitExtensions.Assert (System.Boolean condition) (<00000000000000000000000000000000>:0)
1 IEnumeratorAwaitExtensions+SimpleCoroutineAwaiter.System.Runtime.CompilerServices.INotifyCompletion.OnCompleted (System.Action continuation) (<00000000000000000000000000000000>:0)
2 System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitOnCompleted[TAwaiter,TStateMachine] (TAwaiter& awaiter, TStateMachine& stateMachine) (<00000000000000000000000000000000>:0)
3 ODDFramework.AdProviderBase+d__40.MoveNext () (<00000000000000000000000000000000>:0)

warning CS0618: UnityEngine.Networking.UnityWebRequest.Send() is obsolete

Hey, really cool utility! Makes it really painless to use the new async/await features.

I noticed when I run my game I get the following warning in the console:

Assets/Plugins/AsyncAwaitUtil/Tests/AsyncUtilTests.cs(213,27): warning CS0618:
`UnityEngine.Networking.UnityWebRequest.Send()' is obsolete: `Use SendWebRequest.
It returns a UnityWebRequestAsyncOperation which contains a reference to the WebRequest object.'

OS Licence

Thank you for writing this beautiful piece of code! Can't find the licence though. Can you please specify that?

Time.timeScale = 0 prevents UnitySynchronizationContext.Post

I've created this as an issue with Unity, as it is to do with their implementation of the SynchronizationContext; but it appears setting Time.timeScale = 0f delays the continuations being run on Unity's thread until it is increased above 0.

We found this while using the provided new WaitForUpdate/ Awaiters.NextFrame from a background task.

Unity Ticket: 1057404

this fails on il2cpp builds

this method in C#

private async void DelayedFakeChat()
{
  await new WaitForSeconds(1.0f);
  _signalBus.Fire(...);
}

fails to build in an il2cpp build:

Bulk_Assembly-CSharp_1.cpp:21899:9: assigning to 'RuntimeObject *' (aka 'Il2CppObject *') from incompatible type 'U3CDelayedFakeChatU3Ed__51_t8460B8A56468D8BC08EE7C35ACAE8A2C8ABDECBE'

any ideas? should it even work on il2cpp?

i am on unity 2018.4.2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.