How do I run a simple bit of code in a new thread?

2019-01-02 19:31发布

I have a bit of code that I need to run in a different thread than the GUI as it currently causes the form to freeze whilst the code runs (10 seconds or so).

Assume I have never created a new thread before; what's a simple/basic example of how to do this in C# and using .NET Framework 2.0 or later?

15条回答
泛滥B
2楼-- · 2019-01-02 19:36

Here how can use threads with a progressBar , its just for understing how the threads works, in the form there are three progressBar and 4 button:

 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();
    }
}
查看更多
栀子花@的思念
3楼-- · 2019-01-02 19:37

If you are going to use the raw Thread object then you need to set IsBackground to true at a minimum and you should also set the Threading Apartment model (probably STA).

public static void DoWork()
{
    // do some work
}

public static void StartWorker()
{
    Thread worker = new Thread(DoWork);
    worker.IsBackground = true;
    worker.SetApartmentState(System.Threading.ApartmentState.STA);
    worker.Start()
}

I would recommend the BackgroundWorker class if you need UI interaction.

查看更多
荒废的爱情
4楼-- · 2019-01-02 19:40

Good place to start reading is Joe Albahari.

If you want to create your own thread, this is as simple as it gets:

using System.Threading;
new Thread(() => 
{
    Thread.CurrentThread.IsBackground = true; 
    /* run your code here */ 
    Console.WriteLine("Hello, world"); 
}).Start();
查看更多
像晚风撩人
5楼-- · 2019-01-02 19:40

The ThreadPool.QueueUserWorkItem is pretty ideal for something simple. The only caveat is accessing a control from the other thread.

System.Threading.ThreadPool.QueueUserWorkItem(delegate {
    DoSomethingThatDoesntInvolveAControl();
}, null);
查看更多
牵手、夕阳
6楼-- · 2019-01-02 19:40
// following declaration of delegate ,,,
public delegate long GetEnergyUsageDelegate(DateTime lastRunTime, 
                                            DateTime procDateTime);

// following inside of some client method
GetEnergyUsageDelegate nrgDel = GetEnergyUsage;
IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null);
while (!aR.IsCompleted) Thread.Sleep(500);
int usageCnt = nrgDel.EndInvoke(aR);

Charles your code(above) is not correct. You do not need to spin wait for completion. EndInvoke will block until the WaitHandle is signaled.

If you want to block until completion you simply need to

nrgDel.EndInvoke(nrgDel.BeginInvoke(lastRuntime,procDT,null,null));

or alternatively

ar.AsyncWaitHandle.WaitOne();

But what is the point of issuing anyc calls if you block? You might as well just use a synchronous call. A better bet would be to not block and pass in a lambda for cleanup:

nrgDel.BeginInvoke(lastRuntime,procDT,(ar)=> {ar.EndInvoke(ar);},null);

One thing to keep in mind is that you must call EndInvoke. A lot of people forget this and end up leaking the WaitHandle as most async implementations release the waithandle in EndInvoke.

查看更多
梦该遗忘
7楼-- · 2019-01-02 19:40

I'd recommend looking at Jeff Richter's Power Threading Library and specifically the IAsyncEnumerator. Take a look at the video on Charlie Calvert's blog where Richter goes over it for a good overview.

Don't be put off by the name because it makes asynchronous programming tasks easier to code.

查看更多
登录 后发表回答