How to share My.Settings in multiple application instances ?

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 ?
LVL 14
frankhelkAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

PawełI Design & Develop SoftwareCommented:
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

0
frankhelkAuthor 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.
0
PawełI Design & Develop SoftwareCommented:
we'll that's definitely more complicated you have multiple instances of your console application running, all of which are accessing one file for reads and writes. i think your best bet is to check if the file is in use, I think you can just wrap the file accessing code in a IO exception. let me emphasize "I THINK" at least that's what i'd try.
0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

PawełI Design & Develop SoftwareCommented:
One thing that you could also try is having each instance of the logger create a token (just a file) before it begins writing, and then delete the token when complete. this way any instance that can't create the token can sleep for a couple of seconds and try again.

or you can scrap the whole writing to a text file from the logger instances and create a service that takes in log requests which in turn logs them to a file, this way you'd have multiple instances of your console app passing their logs to one mechanism that would then write the logs to a file, or db.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
PawełI Design & Develop SoftwareCommented:
hi @frankhelk, i'm curious if you ever got this sorted and how.
0
frankhelkAuthor 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.
0
PawełI Design & Develop SoftwareCommented:
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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.