Best multithreading questions in April 2011

How can assigning a variable result in a serious performance drop while the execution order is (nearly) untouched?

15 votes

When playing around with multithreading, I could observe some unexpected but serious performance issues related to AtomicLong (and classes using it, such as java.util.Random), for which I currently have no explanation. However, I created a minimalistic example, which basically consists of two classes: a class "Container", which keeps a reference to a volatile variable, and a class "DemoThread", which operates on an instance of "Container" during thread execution. Note that the references to "Container" and the volatile long are private, and never shared between threads (I know that there's no need to use volatile here, it's just for demonstration purposes) - thus, multiple instances of "DemoThread" should run perfectly parallel on a multiprocessor machine, but for some reason, they do not (Complete example is at the bottom of this post).

private static class Container  {

    private volatile long value;

    public long getValue() {
        return value;
    }

    public final void set(long newValue) {
        value = newValue;
    }
}

private static class DemoThread extends Thread {

    private Container variable;

    public void prepare() {
        this.variable = new Container();
    }

    public void run() {
        for(int j = 0; j < 10000000; j++) {
            variable.set(variable.getValue() + System.nanoTime());
        }
    }
}

During my test, I repeatedly create 4 DemoThreads, which are then started and joined. The only difference in each loop is the time when "prepare()" gets called (which is obviously required for the thread to run, as it otherwise would result in a NullPointerException):

DemoThread[] threads = new DemoThread[numberOfThreads];
    for(int j = 0; j < 100; j++) {
        boolean prepareAfterConstructor = j % 2 == 0;
        for(int i = 0; i < threads.length; i++) {
            threads[i] = new DemoThread();
            if(prepareAfterConstructor) threads[i].prepare();
        }

        for(int i = 0; i < threads.length; i++) {
            if(!prepareAfterConstructor) threads[i].prepare();
            threads[i].start();
        }
        joinThreads(threads);
    }

For some reason, if prepare() is executed immediately before starting the thread, it will take twice as more time to finish, and even without the "volatile" keyword, the performance differences were significant, at least on two of the machines and OS'es I tested the code. Here's a short summary:


Mac OS Summary:

Java Version: 1.6.0_24
Java Class Version: 50.0
VM Vendor: Sun Microsystems Inc.
VM Version: 19.1-b02-334
VM Name: Java HotSpot(TM) 64-Bit Server VM
OS Name: Mac OS X
OS Arch: x86_64
OS Version: 10.6.5
Processors/Cores: 8

With volatile keyword:
Final results:
31979 ms. when prepare() was called after instantiation.
96482 ms. when prepare() was called before execution.

Without volatile keyword:
Final results:
26009 ms. when prepare() was called after instantiation.
35196 ms. when prepare() was called before execution.


Windows Summary:

Java Version: 1.6.0_24
Java Class Version: 50.0
VM Vendor: Sun Microsystems Inc.
VM Version: 19.1-b02
VM Name: Java HotSpot(TM) 64-Bit Server VM
OS Name: Windows 7
OS Arch: amd64
OS Version: 6.1
Processors/Cores: 4

With volatile keyword:
Final results:
18120 ms. when prepare() was called after instantiation.
36089 ms. when prepare() was called before execution.

Without volatile keyword:
Final results:
10115 ms. when prepare() was called after instantiation.
10039 ms. when prepare() was called before execution.


Linux Summary:

Java Version: 1.6.0_20
Java Class Version: 50.0
VM Vendor: Sun Microsystems Inc.
VM Version: 19.0-b09
VM Name: OpenJDK 64-Bit Server VM
OS Name: Linux
OS Arch: amd64
OS Version: 2.6.32-28-generic
Processors/Cores: 4

With volatile keyword:
Final results:
45848 ms. when prepare() was called after instantiation.
110754 ms. when prepare() was called before execution.

Without volatile keyword:
Final results:
37862 ms. when prepare() was called after instantiation.
39357 ms. when prepare() was called before execution.


Mac OS Details (volatile):

Test 1, 4 threads, setting variable in creation loop
Thread-2 completed after 653 ms.
Thread-3 completed after 653 ms.
Thread-4 completed after 653 ms.
Thread-5 completed after 653 ms.
Overall time: 654 ms.

Test 2, 4 threads, setting variable in start loop
Thread-7 completed after 1588 ms.
Thread-6 completed after 1589 ms.
Thread-8 completed after 1593 ms.
Thread-9 completed after 1593 ms.
Overall time: 1594 ms.

Test 3, 4 threads, setting variable in creation loop
Thread-10 completed after 648 ms.
Thread-12 completed after 648 ms.
Thread-13 completed after 648 ms.
Thread-11 completed after 648 ms.
Overall time: 648 ms.

Test 4, 4 threads, setting variable in start loop
Thread-17 completed after 1353 ms.
Thread-16 completed after 1957 ms.
Thread-14 completed after 2170 ms.
Thread-15 completed after 2169 ms.
Overall time: 2172 ms.

(and so on, sometimes one or two of the threads in the 'slow' loop finish as expected, but most times they don't).

The given example looks theoretically, as it is of no use, and 'volatile' is not needed here - however, if you'd use a 'java.util.Random'-Instance instead of the 'Container'-Class and call, for instance, nextInt() multiple times, the same effects will occur: The thread will be executed fast if you create the object in the Thread's constructor, but slow if you create it within the run()-method. I believe that the performance issues described in Java Random Slowdowns on Mac OS more than a year ago are related to this effect, but I have no idea why it is as it is - besides that I'm sure that it shouldn't be like that, as it would mean that it's always dangerous to create a new object within the run-method of a thread, unless you know that no volatile variables will get involved within the object graph. Profiling doesn't help, as the problem disappears in this case (same observation as in Java Random Slowdowns on Mac OS cont'd), and it also does not happen on a single-core-PC - so I'd guess that it's kind of a thread synchronization problem... however, the strange thing is that there's actually nothing to synchronize, as all variables are thread-local.

Really looking forward for any hints - and just in case you want to confirm or falsify the problem, see the test case below.

Thanks,

Stephan

public class UnexpectedPerformanceIssue {

private static class Container  {

    // Remove the volatile keyword, and the problem disappears (on windows)
    // or gets smaller (on mac os)
    private volatile long value;

    public long getValue() {
        return value;
    }

    public final void set(long newValue) {
        value = newValue;
    }
}

private static class DemoThread extends Thread {

    private Container variable;

    public void prepare() {
        this.variable = new Container();
    }

    @Override
    public void run() {
        long start = System.nanoTime();
        for(int j = 0; j < 10000000; j++) {
            variable.set(variable.getValue() + System.nanoTime());
        }
        long end = System.nanoTime();
        System.out.println(this.getName() + " completed after "
                +  ((end - start)/1000000) + " ms.");
    }
}

public static void main(String[] args) {
    System.out.println("Java Version: " + System.getProperty("java.version"));
    System.out.println("Java Class Version: " + System.getProperty("java.class.version"));

    System.out.println("VM Vendor: " + System.getProperty("java.vm.specification.vendor"));
    System.out.println("VM Version: " + System.getProperty("java.vm.version"));
    System.out.println("VM Name: " + System.getProperty("java.vm.name"));

    System.out.println("OS Name: " + System.getProperty("os.name"));
    System.out.println("OS Arch: " + System.getProperty("os.arch"));
    System.out.println("OS Version: " + System.getProperty("os.version"));
    System.out.println("Processors/Cores: " + Runtime.getRuntime().availableProcessors());

    System.out.println();
    int numberOfThreads = 4;

    System.out.println("\nReference Test (single thread):");
    DemoThread t = new DemoThread();
    t.prepare();
    t.run();

    DemoThread[] threads = new DemoThread[numberOfThreads];
    long createTime = 0, startTime = 0;
    for(int j = 0; j < 100; j++) {
        boolean prepareAfterConstructor = j % 2 == 0;
        long overallStart = System.nanoTime();
        if(prepareAfterConstructor) {
            System.out.println("\nTest " + (j+1) + ", " + numberOfThreads + " threads, setting variable in creation loop");             
        } else {
            System.out.println("\nTest " + (j+1) + ", " + numberOfThreads + " threads, setting variable in start loop");
        }

        for(int i = 0; i < threads.length; i++) {
            threads[i] = new DemoThread();
            // Either call DemoThread.prepare() here (in odd loops)...
            if(prepareAfterConstructor) threads[i].prepare();
        }

        for(int i = 0; i < threads.length; i++) {
            // or here (in even loops). Should make no difference, but does!
            if(!prepareAfterConstructor) threads[i].prepare();
            threads[i].start();
        }
        joinThreads(threads);
        long overallEnd = System.nanoTime();
        long overallTime = (overallEnd - overallStart);
        if(prepareAfterConstructor) {
            createTime += overallTime;
        } else {
            startTime += overallTime;
        }
        System.out.println("Overall time: " + (overallTime)/1000000 + " ms.");
    }
    System.out.println("Final results:");
    System.out.println(createTime/1000000 + " ms. when prepare() was called after instantiation.");
    System.out.println(startTime/1000000 + " ms. when prepare() was called before execution.");
}

private static void joinThreads(Thread[] threads) {
    for(int i = 0; i < threads.length; i++) {
        try {
            threads[i].join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

}

It's likely that two volatile variables a and b are too close to each other, they fall in the same cache line; although CPU A only reads/writes variable a, and CPU B only reads/writes variable b, they are still coupled to each other through the same cache line.

In your example, we have two allocation schemes:

new Thread                               new Thread
new Container               vs           new Thread
new Thread                               ....
new Container                            new Container
....                                     new Container

In the first scheme, it's very unlikely that two volatile variables are close to each other. In the 2nd scheme, it's almost certainly the case.

CPU caches don't work with individual words; instead, they deal with cache lines. A cache line is a continuous chunk of memory, say 64 neighboring bytes. Usually this is nice - if a CPU accessed a cell, it's very likely that it will access the neighboring cells too. Except in your example, that assumption is not only invalid, but detrimental.

Suppose a and b fall in the same cache line L. When CPU A updates a, it notifies other CPUs that L is dirty. Since B caches L too, because it's working on b, B must drop its cached L. So next time B needs to read b, it must reload L, which is costly.

If B must access main memory to reload, that is extremely costly, it's usually 100X slower.

Fortunately, A and B can communicate directly about the new values without going through main memory. Nevertheless it takes extra time.

To verify this theory, you can stuff extra 128 bytes in Container, so that two volatile variable of two Container will not fall in the same cache line; then you should observe that the two schemes take about the same time to execute.

Lession learned: usually CPUs assume that adjecent variables are related. If we want independent variables, we better place them far away from each other.

does return "happen after" finally

13 votes

I am trying to convince myself that actions taken in the finally clause happen-before the function return (in the memory consistency sense). From the JVM spec, it is clear that within a thread, program order is supposed to drive the happens-before relationship -- if a happens b in the program order then a happens-before b.

However I have not seen anything explicitly stating that finally happens-before return, so does it?. Or, is there some way that the compiler could reorder the finally clause since it is simply logging.

Motivating example: I have one thread fetching objects out of a database, and putting them into an ArrayBlockingQueue and another thread taking them out. I have some try finally blocks for event timing and I am seeing after affects of the return before the log statement

Thread 1:
public Batch fetch() {
 try {
  log("fetch()+");
  return queryDatabase();
 }
 finally { log("fetch()-"); }
...
workQueue.put(fetch());

Thread 2:
log("take()+");
Batch b = workQueue.take();
log("take()-");

To my great surprise this prints out in an unexpected order. While, yes, logging statements in different threads can appear out of order, there is a time difference of at least 20 ms.

124 ms : take()+
224 ms : fetch()+
244 ms : take()-
254 ms : fetch()-

Note this is not exactly the same question as does finally trump return, I'm not asking what will be returned, but instead about memory consistency and execution order.

@David Heffernan has the correct answer. The JLS specification talks about the behavior of the return statement(including how it interacts with finally blocks) in section 14.17. Copying from there (emphasis mine):

A return statement with an Expression attempts to transfer control to the invoker of the method that contains it; the value of the Expression becomes the value of the method invocation. More precisely, execution of such a return statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the return statement completes abruptly for that reason. If evaluation of the Expression completes normally, producing a value V, then the return statement completes abruptly, the reason being a return with value V. If the expression is of type float and is not FP-strict (§15.4), then the value may be an element of either the float value set or the float-extended-exponent value set (§4.2.3). If the expression is of type double and is not FP-strict, then the value may be an element of either the double value set or the double-extended-exponent value set.

It can be seen, then, that a return statement always completes abruptly.

The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements (§14.20) within the method or constructor whose try blocks contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.

Why are most UI frameworks single threaded?

10 votes

For example, Java swing and android UI both use a single threaded model where a single UI thread is responsible for updating all the UI. What made the framework designers chose one thread model over the other?

Wouldn't multiple threaded UI model potentially give you more performance albeit at the cost of more complexity? I realize that the latter is a big deal because thread related bugs are nasty but I am wondering if there are any other advantages to single threaded model other than simplicity?

What made the framework designers chose one thread model over the other?

From the horse's mouth:

AWT was initially exposed as a normal multi-threaded Java library. But as the Java team looked at the experience with AWT and with the deadlocks and races that people had encountered, we began to realize that we were making a promise we couldn't keep.

This analysis culminated in one of the design reviews for Swing in 1997, when we reviewed the state of play in AWT, and the overall industry experience, and we accepted the Swing team's recommendation that Swing should support only very limited multi-threading.

(Read the whole article, it explains the decision in great detail and states that the exact same problems and eventual move to a single-threaded model had even occured earlier at Xerox PARC - the place where almost everything we consider bleeding edge modern in CS was invented 30 years ago)

Wouldn't multiple threaded UI model potentially give you more performance albeit at the cost of more complexity?

Absolutely not, because drawing the GUI and processing user actions (which is everything the UI thread needs to do) is not going to be the bottleneck in any sane 2D application.

What so different about Node.js's event-driven? Can't we do that in ASP.NET's HttpAsyncHandler?

10 votes

I'm not very experienced in web-programming and stuff, and I haven't actually code anything in Node.Js yet, just curious about the event-driven approach. It does seems good.

The article explain some bad things that could happen when we use thread-based approach to handle request, and should opt for event-driven instead. In thread-based, the cashier/thread is stuck with us until our food/resource is ready. While in event-driven, the cashier send us somewhere out of the request line so we don't block other request while we wait for our food. To scale the blocking thread-based, you need to increase the thread number. This seems to me this is just a bad excuses for not using the thread/threadpool properly.

Couldn't that be properly handled using IHttpAsyncHandler? ASP.NET receive a request, use the ThreadPool and run the handler (BeginProcessRequest), and then inside it we load the file/database with a callback. That Thread should be free to handle other requests. Once the file-reading is done, the ThreadPool is called into action again and execute the remaining response. Not so different for me, so how's that not so scalable?

One of the dis-advantage of the thread-based that I do know is, using thread needs more memory. But only with these, you can enjoy the multi-core benefit. I doubt node.js is not using any of the thread/cores at all.

So, based on just the event-driven vs thread-based (don't bring the "bcoz it's javascript and every browser..." argument), can someone point me out what is the actual benefit of using node.js instead of the existing technology?

That was a long question. Thanks :)

First of all its not multi threaded. This is important. You have to be a very talented programmer to design programs that work perfectly in a threaded environment. Threads are just hard.

You have to be a god to maintain a threaded project where it wasn't designed properly. There are just so many problems that can be hard to avoid in very large projects.

Secondly the whole platform was designed to be run asynchronously. Have you see any ASP.NET project where every single IO interaction was asynchronous? simply put ASP.NET was not designed to be event driven.

Then there's the memory print for the fact that we have a thread per open connection and the whole scaling issue. Correct me if I'm wrong but I don't know how you would avoid creating a new thread for each connection in ASP.NET.

Another issue is that a node.js request idle's when it's not being used or when it's waiting for IO. A C# thread sleeps. Now there is a limit to the amount of these threads that can sleep. In node.js you can easily handle 10k clients at the same time in parallel on one development machine. You try handling 10k threads in parallel on one development machine.

JavaScript itself as a language makes asynchronous coding easier. If your still in C# 2.0 then the asynchronous syntax is a real pain. A lot of developers will simply get confused if your defining Action<> and Function<> all over the place and using callbacks. An ASP.NET project written in an evented way is just not maintainable by your average ASP.NET developer.

As for threads and cores. Node.js is single threaded and scales by creating multiple node processes. If you have a 16 core then you run 16 instances of your node.js server and have a single node.js load balancer in front of it. (Maybe a nginx load balancer if you want).

This was all written into the platform at a very low level right from the start. This was not functionality bolted on later down the line.

Other advantages

Node.js has a lot more to it then above. Above is only why node-js way of handling the event loop is better then doing it with asynchronous capabilities in ASP.NET.

  • performance. It's fast. Real fast.
  • One big advantage of node.js is the low level API. You have a lot of control.
  • You have the entire HTTP server integrated directly into your code then outsourced to IIS.
  • You have the entire nginx vs apache comparison.
  • The entire C10K challenge is handled well by node but not by IIS
  • ajax and json communication feels natural and easy.
  • real time communication is one of the great things about node.js. It was made for it.
  • plays nicely with document based nosql databases.
  • Can run a TCP server aswell. Can do file writing access, can run any unix console command on the server.
  • You query your database in javascript using for example couch db and map/reduce. You write your client in JavaScript. There are no context switches whilst developing on your web stack.
  • rich set of community driven open source modules. Everything in node.js is open source
  • small footprint and almost no dependecies. You build the node.js source yourself.

disadvantages of node.js

It's hard. It's young. As a skilled JavaScript developer I have difficulty writing a website with node.js just because of the low level nature and the level of control I have. It feels just like C. A lot of flexibility and power either to be used for me or to hang me.

The API is not frozen. It's changing rapidly. I can imagine having to rewrite a large website completely in 5 years because of the amount node.js will have changed by then. It is do-able, you just have to be aware that maintenance on node.js websites is not cheap.

further reading

http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/

http://blip.tv/file/2899135

http://nodeguide.com/

C# WPF Update a progressbar from another thread

10 votes

Hi, I'm stuck trying to update a progressbar from other threads ran in a different class. To explain what I do I think a picture will be better. I want to update the progressbar in the //HERE point :enter image description here

I've tried using a delegate, tried with ReportProgress and I think i've basically tried to use everything google reported in the first 100 results, without success. I'm still learning WPF and this might be silly way to proceed, i'm looking for a quick and dirty way to get the work done but feel free to tell me what I should redesign for a cleaner application.

EDIT : More code.

In ExecutorWindow.xaml.cs :

public void RunExecutor()
{
    // CREATE BACKGROUNDWORKER FOR EXECUTOR
    execBackground.DoWork += new DoWorkEventHandler(execBackground_DoWork);
    execBackground.RunWorkerCompleted += new RunWorkerCompletedEventHandler(execBackground_RunWorkerCompleted);
    execBackground.ProgressChanged += new ProgressChangedEventHandler(execBackground_ProgressChanged);
    execBackground.WorkerReportsProgress = true;
    execBackground.WorkerSupportsCancellation = true;
    // RUN BACKGROUNDWORKER
    execBackground.RunWorkerAsync();
}
private void execBackground_DoWork(object sender, DoWorkEventArgs e)
{
    myExecutor = new Executor(arg1, arg2);
    myExecutor.Run();            
}

private void execBackground_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    MessageBox.Show("RunWorkerCompleted execBackground");
}

private void execBackground_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    ExecutorProgressBar.Value += 1;
}

// TESTING 
private void updateProgressBar(int i)
{
    ExecutorProgressBar.Value += i;
}

public delegate void callback_updateProgressBar(int i);

In Executor.cs :

public void Run()
{
    string[] options = new string[2];
    int i = 0;

    while (LeftToRun > 0)
    {
        if (CurrentRunningThreads < MaxThreadsRunning)
        {
            BackgroundWorker myThread = new BackgroundWorker();
            myThread.DoWork += new DoWorkEventHandler(backgroundWorkerRemoteProcess_DoWork);
            myThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerRemoteProcess_RunWorkerCompleted);
            myThread.ProgressChanged += new ProgressChangedEventHandler(backgroundWorkerRemoteProcess_ProgressChanged);
            myThread.WorkerReportsProgress = true;
            myThread.WorkerSupportsCancellation = true;

            myThread.RunWorkerAsync(new string[2] {opt1, opt2});

            // HERE ?
            CurrentRunningThreads++;
            i++;
            LeftToRun--;

        }
    }

    while (CurrentRunningThreads > 0) { }
    logfile.Close();
    MessageBox.Show("All Tasks finished");
}

private void backgroundWorkerRemoteProcess_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker myBackgroundWorker = sender as BackgroundWorker;
    string[] options = (string[])e.Argument;
    string machine = options[0];
    string script = options[1];
    // UPDATE HERE PROGRESSBAR ?
    RemoteProcess myRemoteProcess = new RemoteProcess(machine, script);
    string output = myRemoteProcess.TrueExec();
    // UPDATE HERE PROGRESSBAR ?
    this.logfile.WriteLine(output);
}

private void backgroundWorkerRemoteProcess_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    CurrentRunningThreads--;
}

private void backgroundWorkerRemoteProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //myExecWindow.ExecutorProgressBar.Value = e.ProgressPercentage; // TESTING
    //ExecutorWindow.callback_updateProgressBar(1); // TESTING 
}

EDIT 2 : I got it! Simple in fact, but i guess I've been looking too close to find out.

In my ExecutorWindow class :

private void execBackground_DoWork(object sender, DoWorkEventArgs e)
{
    myExecutor = new Executor(arg1, arg2);
    myExecutor.Run(sender);
}

private void execBackground_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    ExecutorProgressBar.Value += 1;
}

And in my Executor class :

private BackgroundWorker myExecutorWindow;

[...]

public void Run(object sender)
{
            myExecutorWindow = sender as BackgroundWorker;
            string[] options = new string[2];
            int i = 0;

            while (LeftToRun > 0)
            {
                if (CurrentRunningThreads < MaxThreadsRunning)
                {
                    BackgroundWorker myThread = new BackgroundWorker();
                    myThread.DoWork += new DoWorkEventHandler(backgroundWorkerRemoteProcess_DoWork);
                    myThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerRemoteProcess_RunWorkerCompleted);
                    myThread.ProgressChanged += new ProgressChangedEventHandler(backgroundWorkerRemoteProcess_ProgressChanged);
                    myThread.WorkerReportsProgress = true;
                    myThread.WorkerSupportsCancellation = true;

                    myThread.RunWorkerAsync(new string[2] {opt1, opt2});

                    CurrentRunningThreads++;
                    i++;
                    LeftToRun--;      
                }
            }

[...]

private void backgroundWorkerRemoteProcess_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker myBackgroundWorker = sender as BackgroundWorker;
            myBackgroundWorker.ReportProgress(1);
            // PROCESSING MY STUFF HERE
            myBackgroundWorker.ReportProgress(1);
        }

        private void backgroundWorkerRemoteProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            myExecutorWindow.ReportProgress(1);
        }

Thank you !

I got it! Simple in fact, but i guess I've been looking too close to find out.

In my ExecutorWindow class :

private void execBackground_DoWork(object sender, DoWorkEventArgs e)
{
    myExecutor = new Executor(arg1, arg2);
    myExecutor.Run(sender);
}

private void execBackground_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    ExecutorProgressBar.Value += 1;
}

And in my Executor class :

private BackgroundWorker myExecutorWindow;

[...]

public void Run(object sender)
{
            myExecutorWindow = sender as BackgroundWorker;
            string[] options = new string[2];
            int i = 0;

            while (LeftToRun > 0)
            {
                if (CurrentRunningThreads < MaxThreadsRunning)
                {
                    BackgroundWorker myThread = new BackgroundWorker();
                    myThread.DoWork += new DoWorkEventHandler(backgroundWorkerRemoteProcess_DoWork);
                    myThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerRemoteProcess_RunWorkerCompleted);
                    myThread.ProgressChanged += new ProgressChangedEventHandler(backgroundWorkerRemoteProcess_ProgressChanged);
                    myThread.WorkerReportsProgress = true;
                    myThread.WorkerSupportsCancellation = true;

                    myThread.RunWorkerAsync(new string[2] {opt1, opt2});

                    CurrentRunningThreads++;
                    i++;
                    LeftToRun--;      
                }
            }

[...]

private void backgroundWorkerRemoteProcess_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker myBackgroundWorker = sender as BackgroundWorker;
            myBackgroundWorker.ReportProgress(1);
            // PROCESSING MY STUFF HERE
            myBackgroundWorker.ReportProgress(1);
        }

        private void backgroundWorkerRemoteProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            myExecutorWindow.ReportProgress(1);
        }

Insert row in DB while using multithreads?

6 votes

Hi Expert,

Here I am using multi threading and linq to sql.

Here I upload my code snippet:

public class PostService
{ 
    MessageRepository objFbPostRespository = new MessageRepository();
    public void callthreads()
    {
        for (int i = 0; i < 100; i++)
        {
            Thread th = new Thread(postingProcess);
            th.Start();
        }
    }

    public void postingProcess()
    {
        objFbPostRespository.AddLog("Test Multithread", DateTime.Now);
    }
}

Message Repository class

class MessageRepository
{        
    DataClassesDataContext db_Context = new DataClassesDataContext();
    public void AddLog(string Message, DateTime CurrentDateTime)
    {
        FbMessgaeLog FbMessage = new FbMessgaeLog
        {
            Message = Message,
            Time = CurrentDateTime                
        };
        db_Context.FbMessgaeLogs.InsertOnSubmit(FbMessage);
        db_Context.SubmitChanges();
    }
}

When I run it without threads then it's work fine after include thread I was got following error msg:

Error: An item with the same key has already been added.

Thanks in advance...:)

You cannot use a LINQ DataContext in concurrent fashion:

Any instance members are not guaranteed to be thread safe.

Therefore you need to either serialize access (lock) which will be horribly inefficient, or better use a separate context in each thread:

public class PostService
{ 
    public void callthreads()
    {
        for (int i = 0; i < 100; i++)
        {
            Thread th = new Thread(postingProcess);
            th.Start();
        }
    }

    public void postingProcess()
    {
        using (MessageRepository objFbPostRespository = new MessageRepository())
        {
           objFbPostRespository.AddLog("Test Multithread", DateTime.Now);
        }
    }
}

I also hope, for your own sake, that your test has actual logic to wait for the test threads to complete before shutting down... And, of course, properly implement IDisposable in your repository and dispose the context so that the DB connection get placed back in the pool.