return Task.Run和return await Task.Run的区别?

我正在学习async和await,我创建了一个winform程序,并定义了3个按钮,按钮的代码如下:

        private async void button4_Click(object sender, EventArgs e)
        {
            SetTextBox($"button4_Click Start");
            int res = await Task.Run(() =>
            {
                Thread.Sleep(3000);
                return 4;
            });
            SetTextBox($"button4_Click End, {res}");
        }
        private async void button5_Click(object sender, EventArgs e)
        {
            SetTextBox($"button5_Click Start");
            int res = await func5();
            SetTextBox($"button5_Click End, {res}");
        }
        private async Task<int> func5()
        {
            return await Task.Run(() =>
            {
                Thread.Sleep(3000);
                return 5;
            });
        }
        private async void button6_Click(object sender, EventArgs e)
        {
            SetTextBox($"button6_Click Start");
            int res = await func6();
            SetTextBox($"button6_Click End, {res}");
        }
        private async Task<int> func6()
        {
            return await func6_1();
        }
        private async Task<int> func6_1()
        {
            return await Task.Run(() =>
            {
                Thread.Sleep(3000);
                return 6;
            });
        }
        private void SetTextBox(string msg)
        {
            Invoke(new Action(() => { textBox1.Text += $"{msg}\r\n"; }));
        }

三个按钮执行的方法不同,却得到了相同的效果。所以return Task.Run,return await Task.Run以及多次return await Task.Run的区别到底在哪里?还是说他们经过编译器优化之后会得到相同的代码??

被async修饰的方法如果没有await,直接return Task.Run,那么Task内代码块会被同步执行,并不会异步。而加上await关键词之后,代码块会被异步执行,返回void或者TResult。题主列出的代码均采用了异步的方式,且sleep都是三秒,那么结果当然是一样的。