如何使 UniTaskVoid 订阅事件?

huangapple go评论73阅读模式
英文:

How UniTaskVoid subscribe to an event?

问题

UniTask的文档建议避免使用"async void",而是使用UniTaskVoid。但我找不到订阅事件的解决方案。

async void subscription
public class WindowGamePause : WindowView
{
    [SerializeField] private Button _restartGameButton;

    private void Awake()
    {
        _restartGameButton.onClick.AddListener(RestartGame); 
    }
    
    private async void RestartGame()
    {
        await Close();
        _gameManager.RestartGame();
    }
}
async UniTaskVoid subscription??

public class WindowGamePause : WindowView
{
    [SerializeField] private Button _restartGameButton;

    private void Awake()
    {
        _restartGameButton.onClick.AddListener(RestartGame); //怎么做?
        _restartGameButton.onClick.AddListener(RestartGame().Forget); //不工作正常 - 方法在这一行触发
    }
    
    private async UniTaskVoid RestartGame()
    {
        await Close();
        _gameManager.RestartGame();
    }
}

[更新]

我找到了一些解决方案。它运行正常,但我做错了什么,因为Rider说:"可以消除闭包:方法有重载以避免创建闭包"。但我没有任何想法如何避免闭包。

public class WindowGamePause : WindowView
{
    [SerializeField] private Button _restartGameButton;

    private void Awake()
    {
        _restartGameButton.onClick.AddListener(RestartGame);
    }
    
    private void RestartGame()
    {
        UniTask.Void( async () =>
        {
            await Close();
            _gameManager.RestartGame();
        });
    }
}

如何使 UniTaskVoid 订阅事件?

英文:

UniTask's documentation recommends to avoid "async void" and use UniTaskVoid instead. But I cannot find solution to subscribe to events

async void subscription

public class WindowGamePause : WindowView
{
    [SerializeField] private Button _restartGameButton;

    private void Awake()
    {
        _restartGameButton.onClick.AddListener(RestartGame); 
    }
    
    private async void RestartGame()
    {
        await Close();
        _gameManager.RestartGame();
    }
}

async UniTaskVoid subscription??

public class WindowGamePause : WindowView
{
    [SerializeField] private Button _restartGameButton;

    private void Awake()
    {
        _restartGameButton.onClick.AddListener(RestartGame); //What to do?
        _restartGameButton.onClick.AddListener(RestartGame().Forget); //Doesn't work correctly - the method fires on the line
    }
    
    private async UniTaskVoid RestartGame()
    {
        await Close();
        _gameManager.RestartGame();
    }
}

[UPDATE]

I found some solution. It works fine but I do something wrong because Rider says: "Closure can be eliminated: method has overload to avoid closure creation". And I don't have any ideas to avoid closures.

public class WindowGamePause : WindowView
{
    [SerializeField] private Button _restartGameButton;

    private void Awake()
    {
        _restartGameButton.onClick.AddListener(RestartGame);
    }
    
    private void RestartGame()
    {
        UniTask.Void( async () =>
        {
            await Close();
            _gameManager.RestartGame();
        });
    }
}

如何使 UniTaskVoid 订阅事件?

答案1

得分: 1

你可以简单地添加一个中间的void,如下所示:

private void Awake()
{
    _restartGameButton.onClick.AddListener(RestartGame);
}

private void RestartGame()
{
    RestartGame.Forget();
}

或者,你也可以使用lambda表达式来实现,但是这样你无法在需要时移除监听器:

_restartGameButton.onClick.AddListener(() => RestartGameAsync().Forget());

问题在于,为了调用 Forget,你已经必须调用该方法并返回一个 UniTaskVoid,这将立即执行。

英文:

You can always simply add an in-between void like

private void Awake()
{
    _restartGameButton.onClick.AddListener(RestartGame);
}

private void RestartGame()
{
    RestartGame.Forget();
}

private async UniTaskVoid RestartGameAsync()
{
    await Close();
    _gameManager.RestartGame();
}

This basically could also be done with a lambda (but then you can't remove the listener in case it is ever needed)

_restartGameButton.onClick.AddListener(() => RestartGameAsync().Forget());

The problem is that in order to call Forget you already have to call the method and return a UniTaskVoid which will be immediately running.

huangapple
  • 本文由 发表于 2023年2月8日 17:35:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383767.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定