Why the fuck does threading get so stupid when you need to make them talk?


  • Garbage Person

    Seriously. This shit is retarded. Every time I need to do something like this, I have to beat my head against the same wall because I can never seem to remember how the hell it works. Documentation is... Piss poor because this is the fucking Internet and nobody here knows how to program worth a shit (and the MSDN examples come in two varieties - either poorly explained spaghetti code that would work if I bothered figuring it out, or too damned simplistic to get the job done).

     

    For some damned stupid reason, I have this stupid delegate, which, on any invoke except the first, bombs out silently and causes the rest of the fucking function to be skipped. Examination of the debug log shows that some sort of exception is being thrown by the Forms dll, but it doesn't bubble up to my level - which means it SURE AS HELL shouldn't skip out of my function.

     

    All of this stupid drama for a stupid loading screen because my users can't wait 30 seconds without doubleclicking the icon again (thus compounding the problem) while it downloads several fucking megabytes of data.

    Relevant source: 

     

     

        Private Sub printingAppMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim t As New Thread(AddressOf runLoadScreen)
    t.Start()

    Dim detailCallback As New updateLoadScreenDetail(AddressOf loadscreen.setDetailText)
    detailCallback.Invoke("Contacting server...") 'Works great here.
    Dim ws As New webService

    detailCallback.Invoke("Downloading contests...") 'Blows up here.
    VcategoriesWithEntriesDetailBindingSource.DataSource = ws.ExecuteDataset(ConfigurationManager.AppSettings("api_key"), "SQL goes here").Tables(0)

    detailCallback.Invoke("Rendering contest lists...")
    gvJSContestsWithEntries.DataSource = VcategoriesWithEntriesDetailBindingSource

    detailCallback.Invoke("Downloading departments...")
    topLevelCategoriesBindingSource.DataSource = ws.ExecuteDataset(ConfigurationManager.AppSettings("api_key"), "This code likes dongs").Tables(0)
            detailCallback.Invoke("Rendering department lists...")
    gvJSDepartments.DataSource = topLevelCategoriesBindingSource
    gvWRDepartments.AutoGenerateColumns = True
    gvWRDepartments.DataSource = topLevelCategoriesBindingSource
           detailCallback.Invoke("Done. Disconnecting.")
    ws.Dispose()

    End Sub

    Delegate Sub updateLoadScreenDetail(ByVal text As String)
    Delegate Sub updateLoadScreenValue(ByVal val As Integer)


    Private Sub runLoadScreen()
    Application.Run(loadscreen)
    End Sub

    And over in the load screen:

        Public Sub setDetailText(ByVal text As String)
    detailText = text
    End Sub

    (and nothing else of abnormal note in here)

     

    Also, have I ever told you I hate VB?


  • Garbage Person

     *head explodes* I just pulled down the shiny "Programming Visual Basic 2008" O'Reilly book off my shelf. It doesn't even MENTION threading. Seriously. Not only does it not have a chapter, it isn't even in the INDEX. How the FUCK can a book on a language not include FUCKING THREADING? What kind of retarded-assed amatuer hour is this?

     

    At any rate, I have a bit of a handle on what's going on - the loadscreen object is still owned by the main thread because I declare it there - the only reason it works the first time is because the new thread isn't even done initializing when it executes. My difficulties here seem to stem from the fact that in this case, my worker thread is the main thread and the GUI is in a new thread - whereas in every other case like this I've written, the GUI is in the main thread and the workers are seperate threads.

     

    And no, I can't just move the declaration of the new thread, because then I won't be able to point to its setDetailText function.



  • @Weng said:

    At any rate, I have a bit of a handle on what's going on - the loadscreen object is still owned by the main thread because I declare it there - the only reason it works the first time is because the new thread isn't even done initializing when it executes. My difficulties here seem to stem from the fact that in this case, my worker thread is the main thread and the GUI is in a new thread - whereas in every other case like this I've written, the GUI is in the main thread and the workers are seperate threads.

     

    And no, I can't just move the declaration of the new thread, because then I won't be able to point to its setDetailText function.

     

    ZOMG OMG OMG NOBODY EVER THOUGHT OF HOEW TOO CALL A CONTROL FROM ANOTHER THREAD EVAR!!!1

    Er um ... like this --> http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

    It's hardly undocumented.


  • Garbage Person

     Yes, I've read the fucking documentation. Twice. And not just that documentation, but every half-assed fucktard on the entire god damned first 3 pages of Google (none of whom seem to know what they're doing anyway) - Except for whatever retarded-assed reason, it's decided that, regardless of the fact that I'm doing it right (Unless I'm NOT doing it right, see entries on: "Burnout" and "Project Hatred" and "I've logged 400 hours on this in the past 3 and a half weeks and am about to send them a bill for half their fucking company so that I can possibly buy back some of my sanity") it's going to continue being utterly fucking useless. Conceptually speaking, my code is, as far as I can tell, IDENTICAL to both examples and to previous, working code.

     

    I can't even get the SIMPLE case correct - that is, not passing data back and forth between the two threads, but instead just showing a form in the new thread, and then closing it later - it never fucking closes. Ever. I'm rather unclear on how a static object can manage to ignore function calls, even across thread boundaries (which it isn't because we're still closing it from within the same fucking thread)

     

    Seriously - this shit should NOT be this ass-backwards - I'm trying to show a user a god damned form to say "Fuck off and stop clicking the fucking icon" and then take it away after a few dozen lines of code execute. If WinForms were a bit less retarded to start with (i.e. the UI itself is painted by an internally seperate thread) I wouldn't have to do more than write two fucking lines of code. I can do that, but then I get a white box where my "Fuck off" message belongs, because god knows that painting a UI and downloading some fucking data HAVE TO run in the same thread and block each other unless the right threading incantations are spoken.

     

    And the stupid bastard child that is VB's syntax is seriously fucking painful. I hate this language and everyone who willingly uses it. I have to write every line of code twice because I instinctively write it in C#.



  • It's not clear from the vitriol of your posts that you clearly understand the problem; you need to invoke the control methods in the other thread.  Note that the Delegate Invoke method does *not* do that:

    Here's a toy example of a working program that does what you're asking about:

    using System;
    using System.Threading;
    using System.Windows.Forms;

    class DisplayMessageAndLoadInBackground
    {

      Label text;
      Form dlg;
      string detailMessage;
      AutoResetEvent started = new AutoResetEvent(false);
      delegate void SimpleDelegate();
      void setLabelValue() { text.Text = detailMessage; }
      void setDetailMessage(string msg) { detailMessage = msg; text.Invoke(new SimpleDelegate(setLabelValue)); }
      void closeDialog() { dlg.Close(); }
      void messagePump() {
        dlg = new Form();
        text = new Label();
        dlg.Controls.Add(text);
        started.Set();
        dlg.ShowDialog();
      }

      void LongComputation()
      {
            Thread.Sleep(3000);
      }

      void AnotherLongComputation()
      {
            Thread.Sleep(5000);
      }

      void LoadAndSetUp()
      {
        Thread t = new Thread(new ThreadStart(messagePump));
         t.Start();
         started.WaitOne();
         setDetailMessage("Loading...");
         LongComputation();
         setDetailMessage("More loading ...");
         AnotherLongComputation();
         text.Invoke(new SimpleDelegate(closeDialog));
      }

      public static void Main(string []args)
      {
            DisplayMessageAndLoadInBackground dmalib = new DisplayMessageAndLoadInBackground();
            dmalib.LoadAndSetUp();
      }
    }

    Note: The message pump takes place in a separate thread.  This keeps the GUI responsive. 

    Note also: Each control Invoke method call calls the delegate in the message pump thread, not the computing thread.  This is different from just invoking the delegates.



  • @Weng said:

    I just pulled down the shiny "Programming Visual Basic 2008" O'Reilly book off my shelf. It doesn't even MENTION threading. Seriously. Not only does it not have a chapter, it isn't even in the INDEX.

    I wonder what does it say about the SyncLock statement.

    @Weng said:

    How the FUCK can a book on a language not include FUCKING THREADING?

    That's quite understandable, actually, given that the above statement is the only threading-related feature of VB. The rest of threading is language-independent.

    Anyway, can't you just use [url=http://msdn.microsoft.com/en-us/library/bfkbc5a3(VS.80).aspx]the splash screen functionality provided by VB[/url]?


  • Garbage Person

    @arty said:

    It's not clear from the vitriol of your posts that you clearly understand the problem

    Issue resolved 9/20/2009. Action taken: Booze, porn and sleep. Narrative: I got drunk, watched some hardcore pornography and went to bed, Came back in the morning and realized I was being a gigantic moron.

  • Garbage Person

    @Spectre said:

    Anyway, can't you just use the splash screen functionality provided by VB?
    Probably because Google never told me such a thing exists because Googling "<anything> VB.net" produces nothing but a wall of horribly dumb ExpertSexChange articles, CodeProject articles, and archived forum posts. At some point I guess it'll get engrained in my head not to ever, under any circumstances leave the walls of the MSDN documentation.

     

    ... Then again, my MSDN search provider also only turns up social.msdn posts. Seriously, Internet. Static documentation is ALWAYS more relevant than forum posts. *write a new search provider*


  • ♿ (Parody)

    @Weng said:

    Came back in the morning and realized I was being a gigantic moron.
    This seems to solve many more coding problems than is healthy.



  • @boomzilla said:

    @Weng said:

    Came back in the morning and realized I was being a gigantic moron.
    This seems to solve many more coding problems than is healthy.

     

    No kidding.

    I spent 4 sleep-deprived afternoon hours trying to query the correct dataset. The next morning, after a good sleep, I threw away half the code and added 1 inner join. Was done in 5 minutes.

     

    PROTIP:
    Invest in your bed.


  • Garbage Person

    @dhromed said:

    PROTIP:
    Invest in your bed.
    Indeed. It's about time, too. Been sleeping on this one since I was a teenager, and it's starting to get a bit... Saggy (I can't turn it, because the other side looks like a murder took place because it was the unfortunate site of somebody having a seizure while some EMTs tried to get an IV in.)



  • @Weng said:

    it was the unfortunate site of somebody having a seizure while some EMTs tried to get an IV in.
     

    Sometimes you let slip an uncomfortable hint towards your private situation.

    Here:

    PROTIP I, PROTIP II.



  • @Weng said:

    I can't turn it, because the other side looks like a murder took place because it was the unfortunate site of somebody having a seizure while some EMTs tried to get an IV in.
    You're doing it wrong. The correct excuse is "because in my teenage years I used to bring a lot of girls home and a lot of them were virgins".



  • @dhromed said:

    PROTIP I, PROTIP II.
    Oh God don't get an Ikea bed unless you're poor.  The bed frames are fine, but the mattresses will murder your back.  They have no springs and are all foam.  Seriously, just don't.


  • Discourse touched me in a no-no place

    @belgariontheking said:

    They have no springs and are all foam.  Seriously, just don't.
    Not that 'Memory Foam' stuff I take it?



  • @PJH said:

    @belgariontheking said:
    They have no springs and are all foam.  Seriously, just don't.
    Not that 'Memory Foam' stuff I take it?
    No, more like couch cushion foam.

    I recommend a pillowtop mattress as I just purchased one, upgrading from my Ikea mattress.



  • @belgariontheking said:

    @PJH said:

    @belgariontheking said:
    They have no springs and are all foam.  Seriously, just don't.
    Not that 'Memory Foam' stuff I take it?
    No, more like couch cushion foam.

    I recommend a pillowtop mattress as I just purchased one, upgrading from my Ikea mattress.

    A bed made of straw is an upgrade from an Ikea matress.  Their "matresses" are made of roughly the same material as the padding on their stupid Poang chairs.


  • I sleep fine on my sultan.

    You and your pussy backs.



  • @dhromed said:

    I sleep fine on my sultan.

    You and your pussy backs.

    We fat Americans need superior padding.

  • Garbage Person

    @belgariontheking said:

    @dhromed said:

    PROTIP I, PROTIP II.
    Oh God don't get an Ikea bed unless you're poor.  The bed frames are fine, but the mattresses will murder your back.  They have no springs and are all foam.  Seriously, just don't.

    Yeah. I'd rather hit the floor than sleep on an Ikea "mattress"


  •  Hi Weng,

    I looked at your code. Here is the problem. You are not using multiple processes, or CSS to mimic multiple processes. This is not your fault. You were taught not to use multiple processes- or "multiprocessing" as I have named it - in your class.

    There is a lot of misinformation in the information industry. This common idea that threads are good is a perfect example. With the WWW, from here on out and especially in multimedia WWW applications, threads are your enemy. Use them never. Get good at multiprocessing instead. That is wisdom from Gary.

    The problem most programmers have is that they leap straight from single process / single thread thinking to single process / multiple thread thinking. They never stop to consider the possibility of multiple processes, each with a single thread. From now on, I want you to consider this paradigm. It's absolutely essential to good programming, Weng, especially for multimedia Web applications.

    Therefore, the solution to this specific technical problem, and every technical problem that you will have in the future with multimedia, is multiprocessing.

    Again, Weng, you have done nothing wrong. You were just taught a lie. Multiprocessing the answer, by explicit design.

    What I would do is to use the AppDomain object, or perhaps CreateProcess, to put whatever needs to run in parallel into its own process. This will be exactly like another thread, except without sharing memory across thread boundaries. You might find some guidance here: http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf.

    In short, the entire industry is wrong on the threading issue and Gary, and perhaps Edward Lee, are right. This happens a lot to me. Multiprocessing solves this problem and every other multi-page, multi-page source, and multi-media WWW development job. That is why processes are your friend.

    Hope this helps. Let me know what you decide to do. I will help, if you multiprocess, because it's the only solution; now and into the future. –Gary the Frame Fairy



  • @bridget99 said:

     Hi Weng,

    I looked at your code. Here is the problem. You are not using multiple processes, or CSS to mimic multiple processes. This is not your fault. You were taught not to
    use multiple processes- or "multiprocessing" as I have named it - in your class.

    There is a lot of misinformation in the information industry. This
    common idea that threads are good is a perfect example. With the WWW,
    from here on out and especially in multimedia WWW applications, threads are your enemy. Use them never. Get good at multiprocessing instead. That is wisdom
    from Gary.

    The problem most programmers have is that they leap straight from single process / single thread thinking to single process / multiple thread thinking. They never stop to consider the possibility of multiple processes, each with a single thread. From now on, I want you to consider this paradigm. It's absolutely essential to good programming, Weng, especially for multimedia Web applications.

    Therefore, the solution to this specific technical problem, and
    every technical problem that you will have in the future with
    multimedia, is multiprocessing.

    Again, Weng, you have done nothing wrong. You were just taught a lie. Multiprocessing the answer, by explicit design.

    What I would do is to use the AppDomain object, or perhaps CreateProcess, to put whatever needs to run in parallel into its own process. This will be exactly like another thread, except without sharing memory across thread boundaries. You might find some guidance here: http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf.

    In short, the entire industry is wrong on the threading issue and Gary, and perhaps Edward Lee, are right. This happens a lot to me. Multiprocessing solves this problem and
    every other multi-page, multi-page source, and multi-media WWW
    development job. That is why processes are your friend.

    Hope this helps. Let me know what you decide to do. I will help, if
    you multiprocess, because it's the only solution; now and into the future.
    –Gary the Frame Fairy

    Is this spam, a troll or fo' real?



  • @XIU said:

     Is this spam, a troll or fo' real?
    None of the above.  It's an allusion to this front page article.


  • @bstorer said:

    @XIU said:

     Is this spam, a troll or fo' real?

    None of the above.  It's an allusion to this front page article.

    Is it spam? No, I'm not planning to make any money from my attempt to turn "Gary the Frame Fairy" into a meme. But now that you've suggested it, the hweels in my head are turning...

    Is it a troll? Probably a bit of one. 

    Is it for real? My serious advice to the OP and others is that threading is overused. Windows encourages threading over multiprocessing by basically embracing a heavy process / light thread model. But nevertheless, I do think that there is value in looking to put things in another process, versus another thread. I do agree with most of what Dr. Lee says in his article, e.g. that threads are "wildly non-deterministic" and that it's a very big leap from being able to program to being able to write correct multithreaded code.



  • @bridget99 said:

    Is it spam? No, I'm not planning to make any money from my attempt to turn "Gary the Frame Fairy" into a meme. But now that you've suggested it, the hweels in my head are turning...

    Is it a troll? Probably a bit of one. 

    Is it for real? My serious advice to the OP and others is that threading is overused. Windows encourages threading over multiprocessing by basically embracing a heavy process / light thread model. But nevertheless, I do think that there is value in looking to put things in another process, versus another thread. I do agree with most of what Dr. Lee says in his article, e.g. that threads are "wildly non-deterministic" and that it's a very big leap from being able to program to being able to write correct multithreaded code.


    The biggest difference is sharing data between threads. So things like backgrounds threads to get some data without blocking the application can be perfectly in another thread. Stuff that can be completely separated can be in another process without a problem (the System.AddIns assembly allows you to run your add-in in a separate process without having to code anything special) and browsers are now also using it more and more to handle the tabs.

    But still, threads are much easier to manage that running everything in separated processes.

Log in to reply