We help IT Professionals succeed at work.

How to share My.Settings in multiple application instances ?

287 Views
Last Modified: 2017-03-22
Hi, friends,

I have written a (VB).NET console application that does external processing of some text information and is called repeatedly and often from a multithreaded application. Even while each instance runs only for a short time, it's possible that two instances run concurrently.

Unfortunately I observe crashes of the console application, and it rund flawless in the debugger with the same dataset. This behaviour seems to occur more often since I log more data ( = longer run time of each instance = more concurrent processes).

Due to my own convenience I've made use of the My.Settings facility for various program data. This data is updated from time to time by the console application, but it's no problem with what version of that data the application instance runs.

My suspicion is that parallel instances of the console application collide when accessing the application config file.

Unfortunately I don't see anything in the event log nor can I find any crash dump files ...

Any tip how to circumvent that problem ?
Comment
Watch Question

PawełI Design & Develop Software

Commented:
I'm not sure if i'm fully understanding you because my brain is kinda fried, if you're saying that you have more than one thread trying to update a file, then yes this is causing your problem, what you need to do is create a lock around the file to prevent more than one thread accessing it at one time.

if this is your problem, here's a little app i made for my blog to get the point across

using System;
using System.Linq;
using System.Threading;

namespace pc.ThreadLock
{
    enum Straw { Long, Short }
    class Straws
    {
        public int Count { get { return _straws.Count(); } }
        Straw[] _straws;

        public Straw this[int Index]
        {
            get
            {
                var pulledStraw = _straws[Index];

                //shift straws from pulled one left and resize array
                for (; Index + 1 < _straws.Length; Index++)
                    _straws[Index] = _straws[Index + 1];
                Array.Resize(ref _straws, _straws.Length - 1);

                return pulledStraw;
            }
        }

        public Straws(int NumOfStraws, int NumOfShortStraws = 1)
        {
            _straws = new Straw[NumOfStraws];

            while (NumOfShortStraws > 0)
            {
                //pick random index for short straw, if selected index
                //already has short straw, try again.
                var shortStrawIndex = Program.rnd.Next(NumOfStraws);
                if (_straws[shortStrawIndex] == Straw.Short)
                    continue;
                _straws[shortStrawIndex] = Straw.Short;
                NumOfShortStraws--;
            }
        }
    }

    class Program
    {
        public static Random rnd = new Random(DateTime.Now.Millisecond);
        static Straws Straws = new Straws(5, 2);

        //Our lock to prevent concurrent access to the straws object
        static object _lock = new object();

        static void Main(string[] args)
        {
            var Pawel = new Thread(PullStraw);
            Pawel.Name = "Pawel";

            var Magda = new Thread(PullStraw);
            Magda.Name = "Magda";

            var Jakub = new Thread(new ThreadStart(PullStraw));
            Jakub.Name = "Jakub";

            var Tomek = new Thread(new ThreadStart(PullStraw));
            Tomek.Name = "Tomek";

            var Marin = new Thread(new ThreadStart(PullStraw));
            Marin.Name = "Marin";

            var Threads = new Thread[] { Pawel, Magda, Jakub, Tomek, Marin };

            foreach (var t in Threads)
                t.Start();
        }

        static void PullStraw()
        {
            Straw PulledStraw;

            //restrict access to just one thread at a time
            lock (_lock)
            {
                PulledStraw = Straws[rnd.Next(Straws.Count - 1)];
            }

            var output = $"{Thread.CurrentThread.Name} pulled {PulledStraw.ToString()}";
            Console.WriteLine(output);
        }
    }
}

Open in new window

CERTIFIED EXPERT

Author

Commented:
The problem is not threads but complete instances. The calling application is multithreaded (massive), and each thread could spawn an instance of my application ... and these multiple instances may  - I suspect - collide when  concurrently accessing My.Settings.
PawełI Design & Develop Software
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION
I Design & Develop Software
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION
PawełI Design & Develop Software

Commented:
hi @frankhelk, i'm curious if you ever got this sorted and how.
CERTIFIED EXPERT

Author

Commented:
Thanks for asking at the right time. Got it fixed yesterday, and it was something completely different.

My console process gets started from a service and therefore runs completely in the background. For debugging purposes I've had - besides of logging to a file - a instruction
[code]Console.WriteLine(...)[/code]
within my logging method. That worked very nice when running in VS, I could read all the logging output in the console window.

When running on the target machine, called from the service, there's no console window. Obviously (now) the output to stdout is buffered and diplayed in the console window asynchronous to the process. So that Console.WriteLine() instruction's output was stuffed into an internal buffer of (as I know now ....) 4k size. When that buffer got full, my process got deadlocked, waiting for the non-existent window to drain the buffer. Booom.

Due to the fact that this is not a real crash, I never got a message about a failure.

To nail that down I had to include a separate thread that waited for the process to hang and then logged a stack trace of the main thread. And even then I had to notice that the size of the text logged to file (which was written prior to writing to the console)  was just a bit more than 4k and a third look on the stack trace 'til I realized where the problem is.

A real nasty one.

Even while it was not your tip that led me to the final solution I award the points to you. Your tip was one thing I tried in between and it's a good advice for such sync problems.
PawełI Design & Develop Software

Commented:
Oh man, that's rough, honestly i don't know if i'll ever have that problem, but i sure as hell wont forget the dangers of a console.writeline. and I appropriate the points.

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions