使用System.Threading.Task访问winform控件会卡住

Jes*_*aya 4 .net c# multithreading winforms task-parallel-library

新的Task类在WPF中运行良好.但是在Winforms中,每次尝试访问Winform控件时它总是卡住.下面的"InvokeRequired"例程一直在使用BackgroundWorker和Thread类来防止跨线程操作错误.但是,由于某些原因,当涉及到Task时,它会停留在Invoke方法上.救命 ?

这是一个示例代码.我使用.NET 4.5.1框架.

using System;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinformTaskDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string now = DateTime.Now.ToString();
            Task t = new Task(() => { setText(now); });
            t.Start();
            t.Wait();
        }

        private void setText(string text)
        {
            if (textBox1.InvokeRequired)
            {
                textBox1.Invoke(new Action(() => textBox1.Text = text)); //stuck forever here
            }
            else
            {
                textBox1.Text = text;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 5

你自己陷入困境.您运行任务但使用同步阻止它Task.Wait().此操作会阻止UI线程.现在,从后台线程,您同步将消息发布到刚刚阻止的同一UI消息循环.因此,陷入僵局.

对此的解决方案不是阻止Task,而是异步等待它.虽然问题确实浮现在脑海中,但如果您只是与UI元素进行交互,那么为什么首先在后台线程中进行?

private async void button1_Click(object sender, EventArgs e)
{
     string now = DateTime.Now.ToString();
     await Task.Run(() => { setText(now); });
}
Run Code Online (Sandbox Code Playgroud)

  • 这是解决方案.很高兴知道异步也适用于winform事件. (2认同)