예제 #1
0
        private static async IAsyncEnumerable <int> CoroutineA(
            [EnumeratorCancellation] CancellationToken token)
        {
            var inputIdler = new InputIdler();

            for (int i = 0; i < 80; i++)
            {
                // yield to the event loop to process any keyboard/mouse input first
                await inputIdler.Yield(token);

                // now we could use Task.Run for this
                // but let's pretend this code must execute on the UI thread
                Console.SetCursorPosition(0, 0);
                Console.Write($"{nameof(CoroutineA)}: {new String('A', i)}");

                yield return(i);
            }
        }
예제 #2
0
        private static async IAsyncEnumerable <int> CoroutineB(
            [EnumeratorCancellation] CancellationToken token)
        {
            var inputIdler = new InputIdler();

            for (int i = 0; i < 80; i++)
            {
                // yield to the event loop to process any keyboard/mouse input first
                await inputIdler.Yield(token);

                Console.SetCursorPosition(0, 1);
                Console.Write($"{nameof(CoroutineB)}: {new String('B', i)}");

                // slow down CoroutineB
                await Task.Delay(25, token);

                yield return(i);
            }
        }
예제 #3
0
        private Form CreateUI()
        {
            var form = new Form
            {
                Text          = Application.ProductName,
                Width         = 800, Height = 400,
                StartPosition = FormStartPosition.CenterScreen
            };

            var textBox = new TextBox
            {
                Multiline     = true,
                AcceptsReturn = true,
                Dock          = DockStyle.Fill
            };

            form.Controls.Add(textBox);

            var menu = new MenuStrip {
                Dock = DockStyle.Top
            };
            var actionMenu = new ToolStripMenuItem("Coroutines");

            menu.Items.Add(actionMenu);
            var actionItems = actionMenu.DropDownItems;

            actionItems.Add(
                "IEnumerable/Pull-based coroutines", null,
                StartCoroutineDemo);

            actionItems.Add(
                "IAsyncEnumerable/Push-based coroutines", null,
                StartAsyncCoroutineDemo);

            actionItems.Add(
                "IAsyncEnumerable/Push-based mutual coroutines", null,
                StartAsyncCoroutineDemoMutual);

            menu.Items.Add(
                "Stop", null, (s, e) => Stop());

            menu.Items.Add(
                "Close", null, (s, e) => form.Close());

            CancellationTokenSource?uiWorkCts = null;

            menu.Items.Add(
                "Show TickCount", null, async(s, e) => {
                // not good: do some silly work on the UI thread in a hot loop
                uiWorkCts?.Cancel();
                uiWorkCts = CancellationTokenSource.CreateLinkedTokenSource(Token);
                uiWorkCts.CancelAfter(5000);
                var idler = new InputIdler();
                while (!uiWorkCts.Token.IsCancellationRequested)
                {
                    textBox.Text = $"TickCount: {Environment.TickCount}";
                    form.Refresh();
                    if (InputIdler.AnyInputMessage())
                    {
                        // process messages
                        await idler.Yield(CancellationToken.None);
                    }
                }
                textBox.Text = String.Empty;
            });

            form.MainMenuStrip = menu;
            form.Controls.Add(menu);
            form.FormClosing += (s, e) => Stop();

            return(form);
        }