Proper loading of a document in the background stream

Of the applications I wrote, and the one that I inherited, I have a constant desire to better understand thread safety issues when loading data into a background thread. Suppose I have a simple single-line Windows Forms application with a Download button and BackgroundWorker:

My App in the Visual Studio Designer

The handler of the handler Clickcalls loadBackgroundWorker.RunWorkerAsync(), and the handler of the worker DoWorkcreates and initializes an object of the type Document, which, after loading, stores in the property LoadedDocument. In the handler, RunWorkerCompleteda MessageBoxdisplays properties LoadedDocument. I know this is hard to imagine, so I am including the full code. Sorry to ask the question for so long.

Here's the form code:

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace BackgroundLoadTest
{
    public partial class Form1 : Form
    {
        private Document _loadedDocument;
        public Document LoadedDocument
        {
            get
            {
                lock (this)
                {
                    return _loadedDocument;
                }
            }
            set
            {
                lock (this)
                {
                    _loadedDocument = value;
                }
            }
        }

        public Form1()
        {
            InitializeComponent();
            loadBackgroundWorker.DoWork += new DoWorkEventHandler(loadBackgroundWorker_DoWork);
            loadBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(loadBackgroundWorker_RunWorkerCompleted);
        }

        void loadBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Document d = new Document();
            d.Property1 = "Testing";
            d.Property2 = 1;
            d.Property3 = 2;
            this.LoadedDocument = d;
        }

        void loadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Document loaded with Property1 = " +
                LoadedDocument.Property1 + ", Property2 = " +
                LoadedDocument.Property2 + ", Property3 = " +
                LoadedDocument.Property3);
        }

        private void loadButton_Click(object sender, EventArgs e)
        {
            loadBackgroundWorker.RunWorkerAsync();
        }
    }
}

Here is the code for the class Document:

using System;

namespace BackgroundLoadTest
{
    public class Document
    {
        public string Property1 { get; set; }
        public double Property2 { get; set; }
        public int Property3 { get; set; }
    }
}

My question is:

/ - , , ?

LoadedDocument , , , ? ? , -, , , , .

: , . , , , GUI, . , CPU. , , .

+4
1

, - .

. . ( ) .

, , - LoadedDocument , . , .

DoWorkEventArgs loadBackgroundWorker_DoWork Result, . RunWorkerCompletedEventArgs.Result . :

    void loadBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        Document d = new Document();
        d.Property1 = "Testing";
        d.Property2 = 1;
        d.Property3 = 2;
        e.Result = d;
    }

    void loadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.LoadedDocument = (Document)e.Result;
        MessageBox.Show("Document loaded with Property1 = " +
            LoadedDocument.Property1 + ", Property2 = " +
            LoadedDocument.Property2 + ", Property3 = " +
            LoadedDocument.Property3);
    }

.NET, . .


: , BackgroundWorker

, , BackgroundWorker, , e.Result, .

, , :

    private void WorkerThreadStart(object argument)
    {
        object workerResult = null;
        Exception error = null;
        bool cancelled = false;

        try
        {
            DoWorkEventArgs doWorkArgs = new DoWorkEventArgs(argument);
            OnDoWork(doWorkArgs);
            if (doWorkArgs.Cancel)
            {
                cancelled = true;
            }
            else
            {
                workerResult = doWorkArgs.Result;
            }
        }
        catch (Exception exception)
        {
            error = exception;
        }

        RunWorkerCompletedEventArgs e = 
            new RunWorkerCompletedEventArgs(workerResult, error, cancelled); 

        asyncOperation.PostOperationCompleted(operationCompleted, e);
    }

. . , . , ?

RunWorkerCompletedEventArgs, . :

[HostProtection(SharedState = true)]
public class RunWorkerCompletedEventArgs : AsyncCompletedEventArgs

MSDN :

SharedState true, , .

, , , . ? . ? , .

+3

Source: https://habr.com/ru/post/1568398/


All Articles