当前位置:  开发笔记 > 编程语言 > 正文

如何在新线程中运行一小段代码?

如何解决《如何在新线程中运行一小段代码?》经验,为你挑选了9个好方法。

我有一些代码需要在与GUI不同的线程中运行,因为它当前导致表单在代码运行时冻结(10秒左右).

假设我以前从未创建过新的线程; 什么是如何在C#中使用.NET Framework 2.0或更高版本执行此操作的简单/基本示例?



1> Ed Power..:

Joe Albahari是开始阅读的好地方.

如果你想创建自己的线程,这很简单:

using System.Threading;
new Thread(() => 
{
    Thread.CurrentThread.IsBackground = true; 
    /* run your code here */ 
    Console.WriteLine("Hello, world"); 
}).Start();


@EdPower我认为你应该小心!您可能不希望在执行期间终止的任务的一个示例是将数据保存到磁盘的任务.但是可以肯定的是,如果您的任务适合随时终止,那么旗帜就可以了.我的观点只是*人们需要小心使用旗帜*,因为你没有描述它的目的,而且它的命名很容易让人相信它做的不是它实际做的事情.
将'IsBackground`设置为true时要小心.它可能不会做你认为它做的事情.它的作用是配置当所有前台线程都已经死亡时线程是否会被杀死,或者线程是否会使应用程序保持活动状态.如果您不希望线程在执行期间终止,请不要将`IsBackground`设置为true.

2> Gant..:

BackgroundWorker 似乎是你的最佳选择.

这是我的最小例子.单击按钮后,后台工作程序将开始在后台线程中工作,并同时报告其进度.它还将在工作完成后报告.

using System.ComponentModel;
...
    private void button1_Click(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();

        // this allows our worker to report progress during work
        bw.WorkerReportsProgress = true;

        // what to do in the background thread
        bw.DoWork += new DoWorkEventHandler(
        delegate(object o, DoWorkEventArgs args)
        {
            BackgroundWorker b = o as BackgroundWorker;

            // do some simple processing for 10 seconds
            for (int i = 1; i <= 10; i++)
            {
                // report the progress in percent
                b.ReportProgress(i * 10);
                Thread.Sleep(1000);
            }

        });

        // what to do when progress changed (update the progress bar for example)
        bw.ProgressChanged += new ProgressChangedEventHandler(
        delegate(object o, ProgressChangedEventArgs args)
        {
            label1.Text = string.Format("{0}% Completed", args.ProgressPercentage);
        });

        // what to do when worker completes its task (notify the user)
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        delegate(object o, RunWorkerCompletedEventArgs args)
        {
            label1.Text = "Finished!";
        });

        bw.RunWorkerAsync();
    }

注意:

为了简单起见,我使用C#的匿名方法将所有内容都放在单个方法中,但您总是可以将它们用于不同的方法.

在内部ProgressChangedRunWorkerCompleted处理程序中更新GUI是安全的 .但是,更新GUI DoWork 将导致 InvalidOperationException.


使用System.ComponentModel; (可能会使人们无法进行谷歌搜索,感谢这个有用的代码示例)+1

3> Mark Bracket..:

该ThreadPool.QueueUserWorkItem是相当理想的简单的东西.唯一需要注意的是从另一个线程访问一个控件.

System.Threading.ThreadPool.QueueUserWorkItem(delegate {
    DoSomethingThatDoesntInvolveAControl();
}, null);



4> FallenAvatar..:

快速又脏,但它会起作用:

在顶部使用:

using System.Threading;

简单代码:

static void Main( string[] args )
{
    Thread t = new Thread( NewThread );
    t.Start();
}

static void NewThread()
{
    //code goes here
}

我把它扔进了一个新的控制台应用程序中


@CmdrTallen:那不太对劲.标记为IsBackground = true的线程意味着线程不会停止进程退出,即当所有IsBackground = false的线程退出时,进程将退出
记住标记为IsBackground的线程不会被运行时自动终止.这需要应用程序进行线程管理.如果您将线程标记为非后台,则在线程执行后,线程将终止.
-1.至少您需要将IsBackground设置为true.

5> Spongebob Co..:

这是另一种选择:

Task.Run(()=>{
//Here is a new thread
});


你想要的海绵bob的确切代码样本;-)
此代码不保证您有新线程.决定取决于您正在使用的ThreadPool的当前实现.参见示例/sf/ask/17360801/
@MohsenShakiba,我感兴趣为什么这可能不是最好的方法?它当然非常简洁(我已经使用了一段时间的方法).

6> Andy..:

尝试使用BackgroundWorker类.您可以为代理人提供运行的内容,并在工作完成时收到通知.我链接到的MSDN页面上有一个示例.


@Merus,你能扩展一下那些微妙的限制吗?
您当然可以使用Thread类执行此操作,但BackgroundWorker为您提供了线程完成和进度报告的方法,否则您必须弄清楚如何使用自己.不要忘记你必须使用Invoke与UI交谈!

7> 小智..:

如果你想得到一个值:

var someValue;

Thread thread = new Thread(delegate()
            {                 
                //Do somthing and set your value
                someValue = "Hello World";
            });

thread.Start();

while (thread.IsAlive)
  Application.DoEvents();



8> Redbaron..:

将该代码放在一个函数中(无法在与GUI相同的线程上执行的代码),并触发该代码的执行,如下所示.

Thread myThread= new Thread(nameOfFunction);

workerThread.Start();

在线程对象上调用start函数将导致在新线程中执行函数调用.


@ user50612你在说什么?新线程将在后台运行`nameOfFunction`,而不是在当前GUI线程上运行.`IsBackground`属性确定线程是否会使应用程序保持活动状态:https://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v=vs.110).aspx# ANCHOR_2

9> 小智..:

在这里,如何将线程与progressBar结合使用,仅用于了解线程的工作方式,形式为三个progressBar和4个按钮:

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    Thread t, t2, t3;
    private void Form1_Load(object sender, EventArgs e)
    {

        CheckForIllegalCrossThreadCalls = false;

         t = new Thread(birinicBar); //evry thread workes with a new progressBar


         t2 = new Thread(ikinciBar);


         t3 = new Thread(ucuncuBar);

    }

    public void birinicBar() //to make progressBar work
    {
        for (int i = 0; i < 100; i++) {
            progressBar1.Value++;
            Thread.Sleep(100); // this progressBar gonna work faster
        }
    }

    public void ikinciBar()
    {
        for (int i = 0; i < 100; i++)
        {
            progressBar2.Value++;
            Thread.Sleep(200);
        }


    }

    public void ucuncuBar()
    {
        for (int i = 0; i < 100; i++)
        {
            progressBar3.Value++;
            Thread.Sleep(300);
        }
    }

    private void button1_Click(object sender, EventArgs e) //that button to start the threads
    {
        t.Start();
        t2.Start(); t3.Start();

    }

    private void button4_Click(object sender, EventArgs e)//that button to stup the threads with the progressBar
    {
        t.Suspend();
        t2.Suspend();
        t3.Suspend();
    }

    private void button2_Click(object sender, EventArgs e)// that is for contuniue after stuping
    {
        t.Resume();
        t2.Resume();
        t3.Resume();
    }

    private void button3_Click(object sender, EventArgs e) // finally with that button you can remove all of the threads
    {
        t.Abort();
        t2.Abort();
        t3.Abort();
    }
}

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有