简体   繁体   English

此方法在哪个线程上运行? C#

[英]On what thread does this method runs? C#

I have a method that updates records from the database, and I wonder if this method really runs in my BackGroundWorker thread considering the following: 我有一个更新数据库记录的方法,并且考虑到以下因素,我想知道此方法是否确实在BackGroundWorker线程中运行:

public partial class Form1 : Form
{
    BackgroundWorker bg = new BackgroundWorker();

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
       bg.DoWork += new DoWorkEventHandler(bg_DoWork);
       bg.RunWorkerAsync();
    }

    void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        UpdateDatabaseRecords(); // <-- Does this method runs in my BackGroundWorker?
    }

    private void UpdateDatabaseRecords()
    {
        SqlConnection conn = new SqlConnection();
        // etc...
    }
}

Is there a difference if I coded the update stuffs directly inside the bg_DoWork method? 如果我直接在bg_DoWork方法内部编码更新内容,是否会有区别?
Something like: 就像是:

void bg_DoWork(object sender, DoWorkEventArgs e)
{
    SqlConnection conn = new SqlConnection();
    // etc...
    // do the update codes here instead of doing 
    // it by calling another method.
}

Yes it is executing on a separate thread. 是的,它在单独的线程上执行。 No there wouldn't be a difference thread wise if you put it directly in that method. 不,如果直接将其放在该方法中,就不会有线程差异。

Functions run in the thread that calls them, due to how function calls are implemented. 由于函数调用的实现方式,函数在调用它们的线程中运行。 So, since your background worker is calling the bg_DoWork function, it will be running in the worker's thread. 因此,由于您的后台工作程序正在调用bg_DoWork函数,因此它将在工作程序的线程中运行。

Because the code snippet appears small, there probably won't be a significant difference in calling another function. 由于代码段很小,因此调用另一个函数可能不会有明显的不同。 If you're just doing that little bit of work, then you can have it all in one function. 如果您只是做一点点工作,那么您可以将其全部整合到一个功能中。 If you start to increase the complexity of what the worker does, then you may want to start splitting it into many functions. 如果您开始增加工作者的工作复杂性,那么您可能需要开始将其拆分为许多功能。

No, there is no difference. 不,没有区别。 Invoking a method creates a new stack-frame for the method call, pushes it onto the call-stack for the current thread , and then transfers control to it. 调用方法会为该方法调用创建一个新的堆栈框架,将其压入当前线程的调用堆栈中,然后将控制权转移给它。 It's also possible that the method may be inlined by the JIT compiler, so you may not see any difference in the disassembly between your 'manually inlined' version and your current version. JIT编译器也可以内联该方法,因此您在“手动内联”版本和当前版本之间的反汇编中可能看不到任何区别

Btw, here's the code for BackgroundWorker.RunAsync from reflector: 顺便说一句,这是来自反射器的BackgroundWorker.RunAsync的代码:

public void RunWorkerAsync()
{
    this.RunWorkerAsync(null);
}

public void RunWorkerAsync(object argument)
{
    if (this.isRunning)
    {
        throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerAlreadyRunning"));
    }
    this.isRunning = true;
    this.cancellationPending = false;
    this.asyncOperation = AsyncOperationManager.CreateOperation(null);

    // the important bit
    this.threadStart.BeginInvoke(argument, null, null);
}

As you can see, your code will run in the context of a WorkerThreadStartDelegate.BeginInvoke . 如您所见,您的代码将在WorkerThreadStartDelegate.BeginInvoke的上下文中运行。 This should mean that one of the thread-pool threads will pick it up, which you can verify by testing the value of Thread.CurrentThread.IsThreadPoolThread inside the bg_DoWork method. 这应该意味着一个线程池线程将对其进行拾取,您可以通过测试bg_DoWork方法中的Thread.CurrentThread.IsThreadPoolThread的值来进行验证。

Yes it runs in a separate thread (background). 是的,它在单独的线程(后台)中运行。 The only difference is that you don't have access to the DoWorkEventArgs parameter, but you can pass it to your method. 唯一的区别是您无权访问DoWorkEventArgs参数,但可以将其传递给您的方法。

I don't think so! 我不这么认为!

wrapping it in a method don't make it work in different thread, i think all of your code inside bg_DoWork will work on background worker (including all code on UpdateDatabaseRecords method). 将其包装在方法中不会使其在不同的线程中工作,我认为bg_DoWork所有代码bg_DoWork将在后台工作程序上工作(包括UpdateDatabaseRecords方法上的所有代码)。

there is a ThreadSynchronizationContext class where you can post your method to work on different thread context. 有一个ThreadSynchronizationContext类,您可以在其中发布方法以在不同的线程上下文上工作。

you can test your code on visual studio by put a break point inside bg_DoWork method and UpdateDatabaseRecords method. 您可以在bg_DoWork方法和UpdateDatabaseRecords方法中放置一个断点,从而在Visual Studio上测试代码。 check it out from "Thread Window" from menu "Debug -> Windows-> Thread" investigate it weather it is work on main thread or worker thread. 从“调试-> Windows->线程”菜单的“线程窗口”中检出它,以检查它是否在主线程或辅助线程上工作。

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

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