2010-11-02 3 views
1

У меня есть метод, который обновляет запись из базы данных, и мне интересно, если этот метод действительно работает в моем BackgroundWorker потоке с учетом следующие:На какой поток работает этот метод? C#

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

ответ

3

Да он выполняется в отдельном потоке. Нет, не было бы разницы в потоке, если бы вы выразили это прямо в этом методе.

0

Функции выполняются в потоке, который их вызывает, из-за того, как реализованы вызовы функций. Итак, поскольку ваш фоновый рабочий вызывает функцию bg_DoWork, он будет работать в потоке рабочего.

Поскольку фрагмент кода кажется небольшим, вероятно, не будет существенной разницы в вызове другой функции. Если вы просто выполняете эту небольшую работу, тогда вы можете использовать все это в одной функции. Если вы начнете увеличивать сложность того, что делает рабочий, тогда вы можете захотеть разбить его на многие функции.

0

Нет, нет никакой разницы. Вызов метода создает новый стек стека для вызова метода, толкает его в стек вызовов для текущего потока , а затем передает управление ему. Также возможно, что этот метод может быть встроен компилятором JIT, поэтому вы можете не видеть любую разницу при разборке между вашей «рутинной» версией и текущей версией.

Btw, вот код для 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.

+0

ahh ... что такое 'рефлектор'? – yonan2236

+0

Это декомпилятор для сборщиков .NET. http://www.red-gate.com/products/reflector/ – Ani

+0

ahh ... спасибо :) – yonan2236

0

Да, он работает в отдельной теме (фон). Единственное различие заключается в том, что у вас нет доступа к параметру DoWorkEventArgs, но вы можете передать его вашему методу.

0

Я так не считаю!

обертывание его в методе не заставляет его работать в разных потоках, я думаю, что весь ваш код внутри bg_DoWork будет работать на фоне рабочего (включая весь код по методу UpdateDatabaseRecords).

класс ThreadSynchronizationContext, где вы можете опубликовать свой метод для работы в разных контекстах потоков.

вы можете проверить свой код на визуальной студии, поставив точку останова внутри метода bg_DoWork и метод UpdateDatabaseRecords. проверьте его из «Окно темы» из меню «Отладка -> Windows-> Тема» исследуйте его, погода работает на основном потоке или рабочем потоке.