C# Manually stopping an asynchronous for-statement (typewriter effect)

前端 未结 4 1414
我寻月下人不归
我寻月下人不归 2020-12-29 18:06

I\'m making a retro-style game with C# .NET-Framework, and for dialogue I\'m using a for-statement, that prints my text letter by letter (like

4条回答
  •  温柔的废话
    2020-12-29 18:50

    Avoid async void. Otherwise you can get an Exception that will break your game and you will not able to catch it.

    Then use as less global variables in async methods as possible.

    I suggest CancellationTokenSource as thread-safe way to stop the Type Writer.

    public async Task TypeWriterEffectBottom(string text, CancellationToken token)
    {
        if (this.BackgroundImage != null)
        {
            Debug1.Text = "TypeWriter is active";
            StringBuilder sb = new StringBuilder(text.Length);
            foreach (char c in text)
            {
                if (token.IsCancellationRequested)
                {
                    LblTextBottom.Text = text;
                    break;
                }
                sb.Append(c);
                LblTextBottom.Text = sb.ToString();
                await Task.Delay(30);
            }
            Debug1.Text = "TypeWriter is finished";
        }
    }
    

    Define CTS. It's thread-safe, so it's ok to have it in global scope.

    private CancellationTokenSource cts = null;
    

    Call TypeWriter from async method to be able to await it.

    // set button layout as "Skip text" here
    using (cts = new CancellationTokenSource())
    {
        await TypeWriterEffectBottom(yourString, cts.Token);
    }
    cts = null;
    // set button layout as "Go to the next scene" here
    

    And finally

    private void PbFastForward_Click(object sender, EventArgs e)
    {
        if (cts != null)
        {
            cts?.Cancel();
        }
        else
        {
            // go to the next scene
        }
    }   
    

提交回复
热议问题