【问题标题】:Convert a Thread to a Task [closed]将线程转换为任务 [关闭]
【发布时间】:2017-07-16 10:11:06
【问题描述】:

我正在尝试在以下代码中使用 .Net Task。

Thread hilo;
delegate void delegado(int valor);

private void button2_Click(object sender, EventArgs e)
        {
            hilo = new Thread(new ThreadStart(Proceso1));
            hilo.Start();
        }
public void Proceso1()
        {
            for (int i = 1; i < 101; i++)
            {
                delegado MD = new delegado(Actualizar1);
                this.Invoke(MD, new object[] { i });
                Thread.Sleep(1000);
            }
        }
public void Actualizar1(int valor)
        {
            ProgressBar1.Value = valor;

            int incremento= valor % 4;
            switch (incremento)
            {
                case 1: lblMensaje.Text = "Estamos procesando ."; break;
                case 2: lblMensaje.Text = "Estamos procesando .."; break;
                case 3: lblMensaje.Text = "Estamos procesando ..."; break;
                default: lblMensaje.Text = "Estamos procesando ...."; break;
            }
        }

任务运行时,文本框必须更新,而且,当任务终止或取消时,文本框应该不会更新。

并避免出现中断执行的类似消息:“当前线程不在单线程单元中”

它将用于桌面和网络

谢谢,各种帮助。

【问题讨论】:

  • 由于所有Proceso1 所做的都是将Actualizar1 推送到UI 线程,因此不清楚您要实现什么。这里的线程/任务没有任何好处。
  • 不要在工作线程中使用Invoke(),因为它会导致线程死锁。而是使用BeginInvoke()
  • ....不管怎样,产生一个线程,除了线程编组到 UI 线程之外什么都不做,然后休眠 1 秒是非常浪费的

标签: c# multithreading asynchronous task invoke


【解决方案1】:

这是对异步任务模式的直接转换:

public async void button2_Click(object sender, EventArgs e)
{
    await Proceso1();
}

private async Task Proceso1()
{
    for (int i = 1; i < 101; i++)
    {
        Actualizar1(i);
        await Task.Delay(1000);
    }
}

private void Actualizar1(int valor)
{
    ProgressBar1.Value = valor;

    int incremento = valor % 4;
    switch (incremento)
    {
        case 1: lblMensaje.Text = "Estamos procesando ."; break;
        case 2: lblMensaje.Text = "Estamos procesando .."; break;
        case 3: lblMensaje.Text = "Estamos procesando ..."; break;
        default: lblMensaje.Text = "Estamos procesando ...."; break;
    }
}

也就是说,我不确定这是为了完成什么,你不能只使用 System.Windows.Forms.Timer 来完成更好的工作。

【讨论】:

  • 很确定 Invoke() 不是必需的
  • 可能是,Task 可能在线程池线程上运行,所以我们需要调用以防万一。我想我应该先检查 InvokeRequired。
  • 也许吧。但是不要使用Invoke(),如果有的话使用BeginInvoke()。对小猫更友善
  • @BrandonKramer InvokeRequired 在此代码中将始终为 false。正确编写的代码永远不需要InvokeRequired
  • @BrandonKramer:从async 返回的任务完全不同。更多内容请参见my async intro
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
相关资源
最近更新 更多