Patrick
Patrick

Reputation: 8318

Is threads calling back to creating thread thread safe?

I don't like this code but I always get confused with threads so wanted someone else's input before I suggest a change; Is this thread safe (Psuedo code though based on C#):

class ThreadCreator
{
    private AnObject obj = new AnObject();
    public ThreadCreator()
    {
        for (int i = 0; i < 100; ++i)
        {
            ThingToThread th = new ThingToThread();//don't care about losing ref to th for this question
            th.sendMsg = this.getMessage;
            Thread t = new Thread(th.doThing);
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }
    }

    public void getMessage( string stuff )
    {
        ...
        obj.DoThing(stuff);
        ...
    }
}

class ThingToThread
{
    public delegate void sendMsg(string stuff);

    public void doThing()
    {
        ...
        this.sendMsg("ohh that's interesting");
        ...
    }
}

Upvotes: 1

Views: 128

Answers (2)

Lukazoid
Lukazoid

Reputation: 19426

Your example isn't thread safe, if you wanted thread-safety I would very much advise using a BackgroundWorker for executing in a new thread, but posting messages back to the main thread.

For example:

class ThreadCreator
{
    private AnObject obj = new AnObject();
    public ThreadCreator()
    {
        for (int i = 0; i < 100; ++i)
        {
            ThingToThread th = new ThingToThread();

            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += th.DoWork;
            worker.ProgressChanged += WorkerProgressChanged;
            worker.RunWorkerAsync();
        }
    }

    private void WorkerProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        string stuff = e.UserState as string;
        obj.DoThing(stuff);
    }
}

And your ThingToThread DoWork method would look like:

public void DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;

    worker.ReportProgress(50, "Half way there");

    worker.ReportProgress(100, "Finished");
}

Upvotes: 0

SLaks
SLaks

Reputation: 887657

You aren't calling back to the any other thread.

Your code will execute the delegate on the new thread, just like any other function call.

If getMessage is not thread-safe, your code will break.

Upvotes: 4

Related Questions