简体   繁体   English

在 C# 的构造函数中声明线程

[英]Declaring Thread in a Constructor in C#

I´m currently figuring out threads and how to work with them.我目前正在研究线程以及如何使用它们。 At the same time Im working on my understanding on Events/Global Events (just for context).同时,我正在努力理解事件/全局事件(仅用于上下文)。

I defined a thread inside a object with the function the thread will use on thread.Start().我在 object 中定义了一个线程,该线程将在 thread.Start() 上使用 function。

internal class Name
    {
        private Thread testthread;

        private EventWaitHandle globalEvent;

        private Eventstest evente = new Eventstest(); //Just to add some methods

        public Name(Thread testthread, EventWaitHandle globalEvent)
        {
            this.testthread = testthread;
            this.globalEvent = globalEvent;
        }

        
        public void Execute()
        {
            bool terminate = false;
            bool eventset = false;
            bool rdy = false;

            while (!terminate)
            {
                if (evente.CheckSysEvent(globalEvent)) 
                {
                    eventset = true; //This is just to check with debugger if the event was raised elsewhere
                }
                Thread.Sleep(100);
            }
        }
    }

So now, like in this example in a Windows Forms App, Im trying to set an instance of this class while setting the instance of the thread at the same time (with the work method the should run later on).所以现在,就像在 Windows Forms 应用程序中的这个例子一样,我试图设置这个 class 的实例,同时设置线程的实例(应该稍后运行)。 Im struggling with this part here.我在这里为这部分苦苦挣扎。

private void btn_runThread_Click(object sender, EventArgs e)
        {
            threadClass = new Name(new Thread(ProblemHere), globalEvent);
            threadClass.Execute();            
        }

This is a button which starts the thread with the work its supposed to do.这是一个按钮,它通过它应该做的工作启动线程。 The variable threadClass is just the initialization in the forms1.cs:变量threadClass只是forms1.cs中的初始化:

Name threadClass;

I know that it wants a delegate to pass the method which the thread should use on start.我知道它希望委托传递线程在启动时应使用的方法。 I tried pretty much anything I found and cant make it work.我几乎尝试了我发现的任何东西,但都无法让它发挥作用。 I cant just pass the method, that doesnt work.我不能只是通过方法,那不起作用。 And the stuff I found in the c# documentation is pretty much just passing the method, as far as I understood it.据我了解,我在 c# 文档中找到的内容几乎只是通过方法。 Which is propably wrong.这可能是错误的。 And I just noticed, how am I able to actually call on that property/thread.start if its only created on runtime?我刚刚注意到,如果它只在运行时创建,我怎么能真正调用该属性/thread.start?

Not a full solution, but a bump to get you going:不是一个完整的解决方案,而是一个让你前进的障碍:

What I would suggest is a little refactor like this我建议的是像这样的小重构

internal class Name
{
    private Thread testthread;

    private EventWaitHandle globalEvent;

    private Eventstest evente = new Eventstest(); //Just to add some methods

    public Name(EventWaitHandle globalEvent)
    {
        this.testthread = new Thread(Execute); // Creates a Thread, that is directed to execute `Execute`
        this.globalEvent = globalEvent;
        this.testthread.Start();  // Tells the framework to schedule the thread for execution.
    }
    
    private void Execute()
    {
        bool terminate = false;
        bool eventset = false;
        bool rdy = false;

        while (!terminate)
        {
            if (evente.CheckSysEvent(globalEvent)) 
            {
                eventset = true; //This is just to check with debugger if the event was raised elsewhere
            }
            Thread.Sleep(100);
        }
    }
}

And in the Button handler just do在 Button 处理程序中,只需执行

private void btn_runThread_Click(object sender, EventArgs e)
{
    threadClass = new Name(globalEvent);
}

Mind that there are still a good portion of mistakes and ooopsies, but at least, this will keep your GUI thread running and you may gain an understanding to go on from here.请注意,仍然存在很大一部分错误和错误,但至少,这将使您的 GUI 线程保持运行,并且您可以从这里了解 go。


A totally different approach (if you are willing to consider it) would be to use a System.Windows.Forms.Timer instead.一种完全不同的方法(如果您愿意考虑的话)是使用System.Windows.Forms.Timer代替。 With that you can have a method called every X time, which would check the state of the globalevent as you are trying to get the thread to doing.有了它,您可以每 X 次调用一个方法,当您尝试让线程执行时,它将检查 globalevent 的globalevent The timer, however, makes this a little more convenient.然而,计时器使这更方便一些。

The typical way would be to create the thread in the constructor, as described in the answer by Fildor.典型的方法是在构造函数中创建线程,如 Fildor 的回答中所述。

But I want to point out that using the Thread object directly is rarely the correct way to do things since there are other tools more suited for whatever you are tryibng to do:但我想指出,直接使用 Thread object 很少是正确的做事方式,因为还有其他工具更适合您尝试做的任何事情:

  • If you want to do something compute heavy on a background thread once, and update the UI after it has been done.如果您想在后台线程上进行一次繁重的计算,并在完成后更新 UI。 Use Task.Run and async/await使用Task.Runasync/await
  • If you want to do something every X seconds.如果你想每隔 X 秒做一次。 Use a timer.使用计时器。 There are both timers that run on the main thread or a background thread, see differences between timers .有两个计时器在主线程或后台线程上运行,请参阅timers 之间的区别
  • If you want to run an compute heavy operation in parallel, use Parallel.For , possibly in combination with Task.Run.如果您想并行运行计算繁重的操作,请使用Parallel.For ,可能与 Task.Run 结合使用。
  • If you want to call IO intensive methods without freezing the UI, use async/await in combination with the appropriate Async methods.如果您想在不冻结 UI 的情况下调用 IO 密集型方法,请将async/await与适当的 Async 方法结合使用。
  • If you want to create a producer/consumer or other processing pipeline there is the DataFlow library如果您想创建生产者/消费者或其他处理管道,可以使用DataFlow

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM