unity GetAwaiter和线程之间探究

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor.UIElements;
using UnityEngine;

//GetAwaiter 方法返回的对象必须要继承ICriticalNotifyCompletion或者是INotifyCompletion才能被await
//类的方法中有GetAwaiter 这个类的对象就可以被await
public class GetAwaiterTest : MonoBehaviour
{
    ClickAwaiter clickAwaiter = new ClickAwaiter();

    // Start is called before the first frame update
    async void Start()
    {

        // Thread dd = new Thread(NewThreadRun);
        // dd.Start();

        // dd = new Thread(NewThreadRun1);
        // dd.Start();
        // clickAwaiter.SetResult(true);
        int id = Thread.CurrentThread.ManagedThreadId;
        Debug.Log($"start===>{id}");
        await clickAwaiter;
        id = Thread.CurrentThread.ManagedThreadId;
        Debug.Log($"wait end===> {id}");

        // await new ClickOneAwaiter();
        // await new Task(()=>{return 12;}).ConfigureAwait(false);
    }

    void NewThreadRun(){
        Thread.Sleep(3000);
        clickAwaiter.SetResult(true);//其他线程
    }

    // void NewThreadRun1(){
    //     Thread.Sleep(4000);
    //     tt.Start();
    // }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("space down");
            clickAwaiter.SetResult(true);//主线程
            
        }
    }
}

public class ClickOneAwaiter
{
    public object AsyncState => throw new NotImplementedException();

    public WaitHandle AsyncWaitHandle => throw new NotImplementedException();

    public bool CompletedSynchronously => throw new NotImplementedException();

    public bool IsCompleted => throw new NotImplementedException();

    public ClickAwaiter GetAwaiter(){
        return new ClickAwaiter();
    }
}

public class ClickAwaiter :ClickAwaiter
{
    public T Result;

    public void SetResult(bool state,T result)
    {
        Result = result;
        base.SetResult(state);
    }

    public new T GetResult(){
        return Result;
    }

     public new ClickAwaiter GetAwaiter()
    {
        return this;
    }
}

public class ClickAwaiter : ICriticalNotifyCompletion
{
    public bool IsCompleted { get; set; }

    public bool mState;
    public Action Continuation;
    public void SetResult(bool state)
    {
        mState = state;
       if(mState)_Continuation();
    }

    public void GetResult()
    {
        
    }

    private void _Continuation(){
        var action = Continuation;
        Continuation = null;
        try
        {
            action?.Invoke();
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
    }
    //这个方法使用await时调用并传入一个委托,回调委托内部会调用GetResult()来获取返回值
    public void OnCompleted(Action continuation)
    {
        Continuation += continuation;
        if(mState){
            _Continuation();
        }
        Debug.Log($"OnCompleted====>{continuation}");
    }

    public void UnsafeOnCompleted(Action continuation)
    {
        OnCompleted(continuation);
        Debug.Log($"UnsafeOnCompleted=======>{continuation}");
    }

    //await的时候会被调用,没有写明会隐式调用
    public ClickAwaiter GetAwaiter()
    {
        return this;
    }
}

基本上需要注意的地方都在代码中注释了,如有错误请指出

你可能感兴趣的:(unity,游戏引擎,c#)