这个方法在什么线程上运行? C#

时间:2010-11-02 04:25:49

标签: c# multithreading

我有一个方法可以更新数据库中的记录,我想知道这个方法是否真的在我的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...
    }
}

如果我直接在bg_DoWork方法中编码更新内容,会有区别吗? 类似的东西:

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.
}

5 个答案:

答案 0 :(得分:3)

是的,它正在一个单独的线程上执行。如果你把它直接放在那个方法中,不会有任何差异。

答案 1 :(得分:0)

由于函数调用的实现方式,函数在调用它们的线程中运行。因此,由于你的后台工作者正在调用bg_DoWork函数,它将在worker的线程中运行。

因为代码片段看起来很小,所以在调用另一个函数时可能没有显着差异。如果您只是做了一点点工作,那么您可以在一个功能中完成所有工作。如果你开始增加工作者的复杂性,那么你可能想要开始将它分成许多函数。

答案 2 :(得分:0)

不,没有区别。调用方法会为方法调用创建一个新的堆栈帧,将其推送到当前线程的调用堆栈,然后将控制权转移给它。 JIT编译器也可能会内联该方法,因此您在“手动内联”版本与当前版本之间的反汇编中可能看不到任何差异

顺便说一句,这是反射器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);
}

如您所见,您的代码将在WorkerThreadStartDelegate.BeginInvoke的上下文中运行。这应该意味着其中一个线程池线程将接收它,您可以通过在Thread.CurrentThread.IsThreadPoolThread方法中测试bg_DoWork的值来验证它。

答案 3 :(得分:0)

是的,它在一个单独的线程(背景)中运行。唯一的区别是您无法访问DoWorkEventArgs参数,但可以将其传递给您的方法。

答案 4 :(得分:0)

我不这么认为!

将它包装在一个方法中不会使它在不同的线程中工作,我认为bg_DoWork中的所有代码都适用于后台工作者(包括UpdateDatabaseRecords方法上的所有代码)。

有一个ThreadSynchronizationContext类,您可以在其中发布您的方法以处理不同的线程上下文。

您可以在bg_DoWork方法和UpdateDatabaseRecords方法中设置一个断点,在visual studio上测试您的代码。从菜单“Debug - &gt; Windows-&gt; Thread”中的“Thread Window”中查看它,查看它在主线程或工作线程上的工作情况。