簡體   English   中英

此方法在哪個線程上運行? C#

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

我有一個更新數據庫記錄的方法,並且考慮到以下因素,我想知道此方法是否確實在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.
}

是的,它在單獨的線程上執行。 不,如果直接將其放在該方法中,就不會有線程差異。

由於函數調用的實現方式,函數在調用它們的線程中運行。 因此,由於您的后台工作程序正在調用bg_DoWork函數,因此它將在工作程序的線程中運行。

由於代碼段很小,因此調用另一個函數可能不會有明顯的不同。 如果您只是做一點點工作,那么您可以將其全部整合到一個功能中。 如果您開始增加工作者的工作復雜性,那么您可能需要開始將其拆分為許多功能。

不,沒有區別。 調用方法會為該方法調用創建一個新的堆棧框架,將其壓入當前線程的調用堆棧中,然后將控制權轉移給它。 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的上下文中運行。 這應該意味着一個線程池線程將對其進行拾取,您可以通過測試bg_DoWork方法中的Thread.CurrentThread.IsThreadPoolThread的值來進行驗證。

是的,它在單獨的線程(后台)中運行。 唯一的區別是您無權訪問DoWorkEventArgs參數,但可以將其傳遞給您的方法。

我不這么認為!

將其包裝在方法中不會使其在不同的線程中工作,我認為bg_DoWork所有代碼bg_DoWork將在后台工作程序上工作(包括UpdateDatabaseRecords方法上的所有代碼)。

有一個ThreadSynchronizationContext類,您可以在其中發布方法以在不同的線程上下文上工作。

您可以在bg_DoWork方法和UpdateDatabaseRecords方法中放置一個斷點,從而在Visual Studio上測試代碼。 從“調試-> Windows->線程”菜單的“線程窗口”中檢出它,以檢查它是否在主線程或輔助線程上工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM