Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
l versC#多线程问题_C#_Multithreading_User Interface - Fatal编程技术网

l versC#多线程问题

l versC#多线程问题,c#,multithreading,user-interface,C#,Multithreading,User Interface,文件复制线程正在运行时,我无法让ui线程更新ui。我的最终目标是让动画继续旋转,直到大文件拷贝最终完成,让用户知道程序没有冻结。这是一个非常简单的服务器到服务器文件复制程序 有人能告诉我我做错了什么吗 *原始版本* using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; usi

文件复制线程正在运行时,我无法让ui线程更新ui。我的最终目标是让动画继续旋转,直到大文件拷贝最终完成,让用户知道程序没有冻结。这是一个非常简单的服务器到服务器文件复制程序

有人能告诉我我做错了什么吗

*原始版本*

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

using System.IO;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private Thread workItemsProducerThread;
        private Thread workItemsCopyThread;
        public Form1()
        {
            InitializeComponent();
        }

        private void ResetProgress()
        {
            lblStep1.Image = null;
        }

        private void SetupProgress()
        {
        this.BeginInvoke((MethodInvoker)delegate ()
        {
            lblStep1.Image = global::animation1.Properties.Resources.animation;
        });
    }

        private void fileCopy()
        {           
            File.Copy("Large file source", "Large file destination", true);

        this.BeginInvoke((MethodInvoker)delegate ()
        {
            MessageBox.Show("Done");
        });

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            lblStep1.Image = global::animation1.Properties.Resources.animation;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
        this.workItemsProducerThread = new Thread(new ThreadStart(this.SetupProgress));
        this.workItemsProducerThread.IsBackground = true;
        this.workItemsProducerThread.Start();

        this.SetupProgress();

            this.workItemsCopyThread = new Thread(new ThreadStart(this.fileCopy));
            this.workItemsCopyThread.IsBackground = true;
            this.workItemsCopyThread.Start();


        while (workItemsCopyThread.IsAlive)
        {
            Thread.Sleep(1000); // wait
        }

        MessageBox.Show("Done");
    }

        private void btnStop_Click(object sender, EventArgs e)
        {
            if (this.workItemsProducerThread != null)
            {
                this.workItemsProducerThread.Abort();
                lblStep1.Image = global::animation1.Properties.Resources.animation;
            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            fileCopy();
        }
    }

}

不要在单击处理程序中睡觉。这会冻结UI线程。让时钟处理器退出。在文件复制线程中,当复制为“不”时。使用Invoke(或BeginInvoke)使完成消息框在UI线程上弹出

试试这种老式风格

private void SetupProgress()
        {

            Invoke((MethodInvoker) delegate
            {
                lblStep1.Image = global::animation1.Properties.Resources.animation;
            });

        }


 private Thread TDoSomeWork()
        {
            var t = new Thread(() => DoSomeWork());
            t.Start();
            return t;
        }


TDoSomeWork();

如果我理解正确,我已经进行了上述更正,但仍然遇到相同的症状?没有理由在Task.Run和
async/await
可用时使用Invoke或threads。您需要从单击处理程序中删除:while isalive循环和messagebox。(异步更容易)相反,没有理由在另一个线程上运行SetupProgress。这是个坏主意。好吧,我试过这两个建议,症状仍然一样。我曾尝试从主UI运行SetupProgress,并将begininvoke替换为just invokes,但行为没有改变。@Jay这是因为代码太复杂了。您不需要线程、调用或中止。Henk Holterman的回答显示了使用内置任务编写此代码是多么容易。Run和async/await.Panagiotis,您介意试试我的示例,看看它是否适合您吗?
fileCopy
应该是
async
方法,并从
任务
中移出,您不需要这里的线程池-它是IO方法,它们正是
async
的目标。
private void SetupProgress()
        {

            Invoke((MethodInvoker) delegate
            {
                lblStep1.Image = global::animation1.Properties.Resources.animation;
            });

        }


 private Thread TDoSomeWork()
        {
            var t = new Thread(() => DoSomeWork());
            t.Start();
            return t;
        }


TDoSomeWork();