sending events asynchronously

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • colin

    sending events asynchronously

    Hi,
    Im familiar with c,c++ etc, and Ive spent a week trying to write my
    first app in c#
    it works reasonably well, but im having difficulty getting to grips with
    inter thread signalling etc.

    I have read all about delegates, event handlers, Invoke methods etc, however
    they all seem to have undesribale side effects as I have tried them.

    The hardest part of the aplication is on exit, well I gues I could just
    ignore it and let it fail ungracefully,
    but the usb Bluetooth com device doesnt like that very much, it takes ages
    before it can be opened again.

    I have a seperate thread wich reads from the com port and wich needs to be
    as realtime as possible.
    it also needs to send data to the UI. it can also get stuck for some time in
    the open,read etc, and the UI thread must wait before it exits the app, if
    it waits just as the com thread is about to use invoke to update the UI it
    gets deadlocked.

    using BeginInvoke would be too heavy on the thread pool as the data can be
    quite fast.

    putting the data in a list protected by lock would be ok,
    but then the problem is how to get the UI thread to look,
    polling would be either too slow or use up to much cpu time,
    a secondary thread to wait for the list to become non empty wich could then
    use invoke to update the UI
    this would work but seems to be getting rather complicated.

    idealy I just want to send an event to the main message pump of the UI
    thread wich is how it would be done
    in the lower level languages

    I have tried the OnEvent method but this still just runs the event handler
    in the current thread.

    Is there some equavalent in c# or something that I have overlooked ?

    thanks
    Colin =^.^=


  • Peter Duniho

    #2
    Re: sending events asynchronously

    On Sun, 01 Apr 2007 12:12:17 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
    wrote:
    [...]
    idealy I just want to send an event to the main message pump of the UI
    thread wich is how it would be done in the lower level languages
    >
    I have tried the OnEvent method but this still just runs the event
    handler in the current thread.
    >
    Is there some equavalent in c# or something that I have overlooked ?
    I just posted an answer to a similar question in a different thread.

    Basically, .NET uses the term "event" to describe something that is very
    different from what people used to programming Windows know as an "event",
    but the old Win32 "event" still exists. See, for example, the
    AutoResetEvent class.

    IMHO, it was a mistake for the term "event" to be used given that it
    conflicts with the pre-existing notion of event handles in Win32, because
    it quite often leads to people thinking that the delegate/event handler
    paradigm in .NET is somehow equivalent when in fact it has nothing to do
    with Win32 event handles.

    You can do all of the same event-driven producer/consumer stuff in .NET
    that you can do in Win32. You need not use the delegate/event handler
    stuff, and in fact there's probably no good reason to. Instead you use
    waitable event objects, where AutoResetEvent and ManualResetEven t are the
    two most likely classes to be useful for your purposes.

    Pete

    Comment

    • colin

      #3
      Re: sending events asynchronously

      "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
      news:op.tp4eiwy j8jd0ej@petes-computer.local. ..
      On Sun, 01 Apr 2007 12:12:17 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
      wrote:
      >
      >[...]
      >idealy I just want to send an event to the main message pump of the UI
      >thread wich is how it would be done in the lower level languages
      >>
      >I have tried the OnEvent method but this still just runs the event
      >handler in the current thread.
      >>
      >Is there some equavalent in c# or something that I have overlooked ?
      >
      I just posted an answer to a similar question in a different thread.
      ah yes ive just read it.
      Basically, .NET uses the term "event" to describe something that is very
      different from what people used to programming Windows know as an "event",
      but the old Win32 "event" still exists. See, for example, the
      AutoResetEvent class.
      IMHO, it was a mistake for the term "event" to be used given that it
      conflicts with the pre-existing notion of event handles in Win32, because
      it quite often leads to people thinking that the delegate/event handler
      paradigm in .NET is somehow equivalent when in fact it has nothing to do
      with Win32 event handles.
      yes I gues they are trying to hide the old unsafe windows type event.
      You can do all of the same event-driven producer/consumer stuff in .NET
      that you can do in Win32. You need not use the delegate/event handler
      stuff, and in fact there's probably no good reason to. Instead you use
      waitable event objects, where AutoResetEvent and ManualResetEven t are the
      two most likely classes to be useful for your purposes.
      aha, I have used AutoResetEvent as well to pass com data onto the data
      proceesing thread.
      but the point is I dont want to stop the UI thread by waiting for the com
      event
      wich I assume will have to happen unless I have missed something
      and the com thread certainly doesnt want to wait for anything other than
      data from the com port,
      and im trying to avoid the UI polling to see if there is data to be written
      to the UI.

      The only exeption is when the program ends, it has to wait for the handle to
      close before it can abort the thread,
      and I have put that in OnClosed but the main window is still visible wich is
      undesirable but I couldnt find a better place, it wouldnt let me add a
      Dispose();

      Is there a thread synchronization object wich will create an 'event' in the
      UI task like having a callback
      but always in the UI thread context ? can the 'WindowProc' be utilised in c#
      ?

      The only alternative so far seems yet another thread.

      It seems like microsoft dont want you to write multithreaded UI apps,
      as a result ive come accros a few apps so far wich so obviously do
      everything in the UI thread.
      even the debugger is inefective when the program is stoped not in the UI
      thread.

      thanks
      Colin =^.^=


      Comment

      • Peter Duniho

        #4
        Re: sending events asynchronously

        On Sun, 01 Apr 2007 13:22:07 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
        wrote:
        yes I gues they are trying to hide the old unsafe windows type event.
        I don't know what you mean by that. First, the Win32 event handle isn't
        "unsafe" by any means. Second, they didn't "hide" it. They've simply
        wrapped it in a .NET Framework class (actually, two classes). That's what
        they've done with ALL of the Win32 stuff.
        aha, I have used AutoResetEvent as well to pass com data onto the data
        proceesing thread.
        but the point is I dont want to stop the UI thread by waiting for the com
        event wich I assume will have to happen unless I have missed something
        Well, I think you have missed something.

        For one, I don't see why using BeginInvoke is incompatible with your
        needs. There's no requirement that you call BeginInvoke for every single
        i/o operation. I don't see how something like i/o could consume too many
        resources using BeginInvoke, unless you're reading a single byte at a time
        (and as far as I can recall, calling BeginInvoke on a form does not use a
        thread pool thread...it just posts the invocation on the form's message
        queue). But even if it would, you could simply only call BeginInvoke to
        update the UI when you've read a certain number of bytes, or when a
        certain amount of time has gone by.
        [...]
        The only exeption is when the program ends, it has to wait for the
        handle to close before it can abort the thread,
        Why are you aborting the thread? Aborting a thread is a pretty poor way
        to manage your threads.

        What you should do is simply allow the application to exit normally, and
        include some mechanism for signaling any non-background threads you've
        created to exit. Usually this would involve setting some sort of state
        variable that signals the exit and then doing whatever is appropriate for
        the thread to get it to unblock and check the state variable (such as
        setting an EventWaitHandle instance or closing an i/o handle like a
        Socket). The main thread can go ahead and exit after signaling the other
        threads, and when the other threads are done doing whatever cleanup they
        need to do, the entire process will exit cleanly.

        Alternatively, there's no reason you can't just close the form and put
        your cleanup code after the Application.Run statement in the Program
        module.
        [...]
        Is there a thread synchronization object wich will create an 'event' in
        the UI task like having a callback but always in the UI thread context ?
        Yes. That's what BeginInvoke does for forms. Invoke and BeginInvoke are
        used in situations when something must be executed on the form's thread.
        That's their whole purpose for being in that situation.
        can the 'WindowProc' be utilised in c# ?
        There are ways to add functionality to the window proc in C# but there
        should be no need for you to do that in this case.
        [...]
        It seems like microsoft dont want you to write multithreaded UI apps,
        Frankly, that's a silly assertion. If Microsoft didn't want you to write
        multithreaded UI apps, why in the world would they include so much support
        for multithreading in .NET?

        If anything, multithreading is *easier* in .NET IMHO. Granted, it's not a
        lot easier (all the same old synchronization issues still exist), but in
        the same way that lots of other OS-level stuff has gotten wrapped in more
        convenient classes, so too has the multithreading stuff.
        as a result ive come accros a few apps so far wich so obviously do
        everything in the UI thread.
        even the debugger is inefective when the program is stoped not in the UI
        thread.
        That's true...I do not understand why the debugger does not appear to have
        good thread support any more. I am still looking for the functionality
        I'm used to using, where when I break in the debugger, all threads are
        stopped and I can easily switch from one thread to another to see where
        they are stopped and what their state is.

        But the broken debugger isn't evidence of a general conspiracy against
        multithreaded programming, IMHO. It's just evidence of a failure on the
        part of the Visual Studio team to ensure that the new versions of the
        tools include at least as much functionality as the previous version.

        Pete

        Comment

        • colin

          #5
          Re: sending events asynchronously

          "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
          news:op.tp4lwed x8jd0ej@petes-computer.local. ..
          On Sun, 01 Apr 2007 13:22:07 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
          wrote:
          >
          >yes I gues they are trying to hide the old unsafe windows type event.
          >
          I don't know what you mean by that. First, the Win32 event handle isn't
          "unsafe" by any means. Second, they didn't "hide" it. They've simply
          wrapped it in a .NET Framework class (actually, two classes). That's what
          they've done with ALL of the Win32 stuff.
          only unsafe as in not 'type'safe, in that often data or function pointers
          were usualy converted to longword in the event parameters etc. and "hide" as
          in hidden under wrappers lol
          >aha, I have used AutoResetEvent as well to pass com data onto the data
          >proceesing thread.
          >but the point is I dont want to stop the UI thread by waiting for the com
          >event wich I assume will have to happen unless I have missed something
          >
          Well, I think you have missed something.
          >
          For one, I don't see why using BeginInvoke is incompatible with your
          needs. There's no requirement that you call BeginInvoke for every single
          i/o operation. I don't see how something like i/o could consume too many
          resources using BeginInvoke, unless you're reading a single byte at a time
          (and as far as I can recall, calling BeginInvoke on a form does not use a
          thread pool thread...it just posts the invocation on the form's message
          queue). But even if it would, you could simply only call BeginInvoke to
          update the UI when you've read a certain number of bytes, or when a
          certain amount of time has gone by.
          Well from what I have read of BeginInvoke it does use a another thread from
          the pool to call invoke,
          not just posting the message on the thread message queue, if it did this
          that would be fine.
          It seems crazy it doesnt do that, maybe I read something that was wrong or
          grossly out of context.
          Im sure it was invoked through a pool thread though..

          I dont realy have the option of waiting for certain amount of time to go by
          in the com thread,
          or waiting for a number of data items.
          the com task is high priority so it is possible it would queue up many
          requests.
          and it is also possible it will suddenly stop.
          >[...]
          >The only exeption is when the program ends, it has to wait for the
          >handle to close before it can abort the thread,
          >
          Why are you aborting the thread? Aborting a thread is a pretty poor way
          to manage your threads.
          What you should do is simply allow the application to exit normally, and
          include some mechanism for signaling any non-background threads you've
          created to exit. Usually this would involve setting some sort of state
          variable that signals the exit and then doing whatever is appropriate for
          the thread to get it to unblock and check the state variable (such as
          setting an EventWaitHandle instance or closing an i/o handle like a
          Socket). The main thread can go ahead and exit after signaling the other
          threads, and when the other threads are done doing whatever cleanup they
          need to do, the entire process will exit cleanly.
          well it just has to wait for the thread to get to a certain state before the
          form gets destroyed or it complains about things, in particular if its in
          the middle of an IO call such as open/close wich can take 10 seconds to
          complete. cant remember the exact message it complained with.
          once its waited for it to get to this stage theres no need for anything
          fancy, abort works ok.

          The only issue about exiting uncleanly is the bluesoleil software wont let
          the port be opened without complaining a lot!
          >
          Alternatively, there's no reason you can't just close the form and put
          your cleanup code after the Application.Run statement in the Program
          module.
          that might be a good place to put the code, but I think the form has
          disapeared by then,
          the serial port is part of the form as it was added with the designer,
          maybe this will have to be moved, unless there is somewhere the form
          disapears from screen but not deleted.
          must be somewhere I just havnt found it yet.
          thinking about it maybe this is the crux of the problem. maybe I should move
          the comport to the program class.

          PS:
          hmm actually ive just removed the abort and set an exit flag and dont bother
          to wait anymore,
          this seems to solve the deadlock problem, just need to try make sure it
          exits cleanly with all the possible combinations of switching on and off the
          remote device and stopping starting the pc software etc.
          I was never entirely sure what the error message was complaining about
          exactly enyway.
          I had a background worker thread before wich might have been the cuase of
          the problem.
          >[...]
          >Is there a thread synchronization object wich will create an 'event' in
          >the UI task like having a callback but always in the UI thread context ?
          >
          Yes. That's what BeginInvoke does for forms. Invoke and BeginInvoke are
          used in situations when something must be executed on the form's thread.
          That's their whole purpose for being in that situation.
          >
          >can the 'WindowProc' be utilised in c# ?
          >
          There are ways to add functionality to the window proc in C# but there
          should be no need for you to do that in this case.
          >
          >[...]
          >It seems like microsoft dont want you to write multithreaded UI apps,
          >
          Frankly, that's a silly assertion. If Microsoft didn't want you to write
          multithreaded UI apps, why in the world would they include so much support
          for multithreading in .NET?
          Well yes its included but it seems to be causing a lot of confusion to
          people judging by the amount of posts ive read asking about it, and the
          numerous different explanations.

          Ive written real time operating executives back in the days of 80286, and
          admitdetly ive only been at this a week but I find it frustratingly
          difficult to find what I need when there is so much emphasis on being able
          to create a simple program in 60 seconds lol.
          If anything, multithreading is *easier* in .NET IMHO. Granted, it's not a
          lot easier (all the same old synchronization issues still exist), but in
          the same way that lots of other OS-level stuff has gotten wrapped in more
          convenient classes, so too has the multithreading stuff.
          I agree entiriely that its easier to do this sort of thing with much more
          safety, (as in type safe)
          underneath delegate is a function pointer hidden under heavy wrappers,
          and it may produce less code wich maybe be easier to keep track of,
          but for it to be easier overall im not convinced as yet.

          It would be easier if they removed the need to write any of the
          synchronizing code yourself at least for the main culprits such as the UI
          controls. although deadlock type issues are notoriously difficult to ensure
          they dont happen, but then the new methods are not particularly transparent
          and hence not easy to see such conflicts.
          >as a result ive come accros a few apps so far wich so obviously do
          >everything in the UI thread.
          >even the debugger is inefective when the program is stoped not in the UI
          >thread.
          >
          That's true...I do not understand why the debugger does not appear to have
          good thread support any more. I am still looking for the functionality
          I'm used to using, where when I break in the debugger, all threads are
          stopped and I can easily switch from one thread to another to see where
          they are stopped and what their state is.
          I think its becuase the debugger now has to pass the evaluation methods to
          the correct thread, and if that thread has stopped then it fails.
          >
          But the broken debugger isn't evidence of a general conspiracy against
          multithreaded programming, IMHO. It's just evidence of a failure on the
          part of the Visual Studio team to ensure that the new versions of the
          tools include at least as much functionality as the previous version.
          I realy didnt intend you to take my comment quite so seriously lol
          Pete
          Im looking at the Synchronization Context, it has post and send with
          callback,
          I think if I undesrtand this right so far it might be just what I need
          although I cant find enough concise info on how it works exactly, I gues il
          just try it and see how it works.

          many thanks for you help
          Colin =^.^=


          Comment

          • Peter Duniho

            #6
            Re: sending events asynchronously

            On Sun, 01 Apr 2007 16:51:35 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
            wrote:
            only unsafe as in not 'type'safe, in that often data or function pointers
            were usualy converted to longword in the event parameters etc. and
            "hide" as in hidden under wrappers lol
            Okay.
            Well from what I have read of BeginInvoke it does use a another thread
            from the pool to call invoke, not just posting the message on the thread
            message queue, if it did this that would be fine.
            It seems crazy it doesnt do that, maybe I read something that was wrong
            or grossly out of context.
            Im sure it was invoked through a pool thread though..
            Likely you were reading something about using BeginInvoke on a delegate
            directly. If I recall correctly, that does execute the delegate on a
            thread pool thread.

            But obviously, since when used with a form the whole point is to have the
            delegate run on the form's thread, when you use BeginInvoke on a form, the
            delegate must execute on the form's thread, not a thread pool thread. It
            wouldn't make sense any other way.
            I dont realy have the option of waiting for certain amount of time to go
            by in the com thread, or waiting for a number of data items.
            I never said anything about waiting. Simply keeping track of. At
            appropriate points in your i/o code, you simply check the current time, or
            check the number of bytes transferred since the last update, and if enough
            time has gone by or enough bytes has been transferred, you post your UI
            update.
            the com task is high priority so it is possible it would queue up many
            requests. and it is also possible it will suddenly stop.
            That's the whole point. It wouldn't queue up many requests, because you
            would deliberately fix the code to prevent that. By posting UI updates
            only at particular intervals, you would ensure that not too many updates
            got queued up. Not that I believe that there should be any problem
            posting updates with every i/o operation anyway, but if you believe that's
            a problem there is a simple solution.
            [...]
            that might be a good place to put the code, but I think the form has
            disapeared by then,
            the serial port is part of the form as it was added with the designer,
            maybe this will have to be moved, unless there is somewhere the form
            disapears from screen but not deleted.
            I see no reason for the serial port to be part of the form. That's a
            convenience, and the moment it gets in your way, you should put it
            somewhere else. I don't personally see any reason it should be a problem
            for the form to remain until the application has really shut down, but if
            that's a design requirement for you, it is easy enough to simply
            instantiate the serial port component elsewhere.

            You could, of course, also just hide the form initially while you wait for
            the cleanup to finish.

            And of course, the fact that you include the serial port on the form in
            the designer doesn't mean that you can't keep a reference to it somewhere
            else. Unless the form designer adds code that explicitly disposes the
            serial port component (I didn't check, but I don't see why it would), the
            form can be closed just fine without affecting the serial port.

            There are a number of ways to deal with the application exit scenario, all
            of which seem just fine to me. I doubt that this is an area of your
            program that deserves a lot of hand-wringing. :)
            PS:
            hmm actually ive just removed the abort and set an exit flag and dont
            bother to wait anymore,
            this seems to solve the deadlock problem, just need to try make sure it
            exits cleanly with all the possible combinations of switching on and off
            the remote device and stopping starting the pc software etc.
            Well, as I mentioned, your form thread can exit without affecting the
            other non-background threads in the application. They will continue to
            run until they exit, allowing them to perform whatever cleanup you need
            them to do.
            I was never entirely sure what the error message was complaining about
            exactly enyway.
            Well, "complainin g" isn't a very precise term. You would probably get
            good advice on the meaning of the error, if you actually posted the exact
            text of the error.
            I had a background worker thread before wich might have been the cuase of
            the problem.
            Perhaps. Background threads don't prevent the process from terminating,
            and get aborted automatically. If you have something running on a
            background thread that shouldn't be aborted, that could definitely cause
            an issue.
            Well yes its included but it seems to be causing a lot of confusion to
            people judging by the amount of posts ive read asking about it, and the
            numerous different explanations.
            Multi-threaded code is complicated. Fact is, given how easy it is to get
            into a multi-threaded situation in .NET, it may be that more people are
            writing multi-threaded code than ought to be. But obviously one can do
            multi-threading just fine in .NET.
            Ive written real time operating executives back in the days of 80286, and
            admitdetly ive only been at this a week but I find it frustratingly
            difficult to find what I need when there is so much emphasis on being
            able to create a simple program in 60 seconds lol.
            There's no such thing as a simple multi-threaded program. Yes, .NET makes
            many things much easier. And a person experienced in .NET programming
            definitely CAN create a simple program in "60 seconds" (give or take a
            minute). But what you are doing is not exactly simple, and you can't
            expect to be able to take full advantage of the rapid-deployment aspects
            of .NET before you have taken the time to learn how .NET works.

            IMHO, you should adjust your expectations to be more in line with the
            level of experience you have with .NET. I'm not saying .NET is
            problem-free, but it seems to me that you are spending too much time
            assuming that .NET can't do what you want or that it has fundamental
            problems, rather than exploring the possibility that you just have some
            things to learn before you can efficiently implement solutions in .NET.
            I agree entiriely that its easier to do this sort of thing with much more
            safety, (as in type safe)
            underneath delegate is a function pointer hidden under heavy wrappers,
            and it may produce less code wich maybe be easier to keep track of,
            but for it to be easier overall im not convinced as yet.
            It seems to me that in the context of .NET, delegates are exactly the
            right solution to the same problem function pointers address in C/C++. I
            have not seen delegates as being any more difficult to use than a function
            pointer, and they are type safe. What sort of "convincing " is it that you
            feel hasn't happened yet? It's not like you have to go to any extra work
            to use delegates; they are basically the same as function pointers and
            frankly, I find the syntax more sensible than that used for function
            pointers in C/C++.
            It would be easier if they removed the need to write any of the
            synchronizing code yourself at least for the main culprits such as the UI
            controls. although deadlock type issues are notoriously difficult to
            ensure they dont happen, but then the new methods are not particularly
            transparent and hence not easy to see such conflicts.
            Deadlocks are always an issue, and I don't see how a language can prevent
            them. Perhaps one day, if someone figures out how to make a computer
            program provably correct, we'll get a compiler that does that. Until
            then, we're left with the problem that computer programs can be
            arbitrarily complex and preventing deadlocks isn't possible.

            As far as the cross-thread form execution issue goes, I agree that's a
            pain in the neck. It's unfortunate that rather than simply smoothing over
            that wrinkle, .NET simply propogates the pre-existing Win32 issue. But
            make no mistake...the issue is a Win32 issue, not one of .NET.

            Pete

            Comment

            • colin

              #7
              Re: sending events asynchronously

              "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
              news:op.tp4624s j8jd0ej@petes-computer.local. ..
              On Sun, 01 Apr 2007 16:51:35 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
              wrote:
              ........
              >
              Likely you were reading something about using BeginInvoke on a delegate
              directly. If I recall correctly, that does execute the delegate on a
              thread pool thread.
              >
              But obviously, since when used with a form the whole point is to have the
              delegate run on the form's thread, when you use BeginInvoke on a form, the
              delegate must execute on the form's thread, not a thread pool thread. It
              wouldn't make sense any other way.
              Ah thats confusing if theres 2 ways its done. I found the article again ..


              its a bit long. I havnt re-read it as yet.

              .....
              That's the whole point. It wouldn't queue up many requests, because you
              would deliberately fix the code to prevent that. By posting UI updates
              only at particular intervals, you would ensure that not too many updates
              got queued up. Not that I believe that there should be any problem
              posting updates with every i/o operation anyway, but if you believe that's
              a problem there is a simple solution.
              basicaly your saying you can put the functionaility of queing the updates
              into the thread,
              I was hoping to avoid this functionality here,
              for clarity as much as anything so its clear to see theres little to hold it
              up.
              certain parts of the code need to give confidence to less technical people
              that they will do what they are suposed to.

              So if I do any queing in my own code it wil be through another thread with a
              lock protected queue as ive already written code to do this with the other
              data that gets processed, its a lot simpler than some of the methods I have
              seen in examples.
              >[...]
              Well, as I mentioned, your form thread can exit without affecting the
              other non-background threads in the application. They will continue to
              run until they exit, allowing them to perform whatever cleanup you need
              them to do.
              Ah, now I think I know where the problem was !
              the com thread was initialy a background type added with the express
              designer,
              I thought it was pretty cool you could add all this stuff from there,
              and I just let the program exit with no cares wich probably works for most
              things,
              as it shuts things down when it destroys them.
              using autoflush works fine for the data loging to file too.

              But I was trying to fix an exception wich occured complaining about being
              aborted inside the IO system call.
              Maybe I didnt even need to fix it but I like to see things run smoothly.
              It was a tad vague but I guesed I needed to control the shutdown to wait
              till it was clear of any IO call,
              wich I did and solved the problem, there was already synchronization of the
              open/close with the com write task anyway.
              (the bluetooth thing needs to be closed and reopened inorder to re-establish
              connection if the bluetooth loses conection wich is only detected by it
              going quiet.)
              however it then cuased a deadlock trying to update the UI with invoke while
              the form task ewas waiting.
              so now it just has an exit flag and isnt aborted by the form shuting down
              nor does it wait.
              the com task is also part of the form so the form wont get destroyed before
              the thread exits so I gues the serial port is safe there.

              anyway I think this particular nail is hammered in now thanks for the help.
              Multi-threaded code is complicated. Fact is, given how easy it is to get
              into a multi-threaded situation in .NET, it may be that more people are
              writing multi-threaded code than ought to be. But obviously one can do
              multi-threading just fine in .NET.
              >Ive written real time operating executives back in the days of 80286, and
              >admitdetly ive only been at this a week but I find it frustratingly
              >difficult to find what I need when there is so much emphasis on being
              >able to create a simple program in 60 seconds lol.
              >
              There's no such thing as a simple multi-threaded program. Yes, .NET makes
              many things much easier. And a person experienced in .NET programming
              definitely CAN create a simple program in "60 seconds" (give or take a
              minute). But what you are doing is not exactly simple, and you can't
              expect to be able to take full advantage of the rapid-deployment aspects
              of .NET before you have taken the time to learn how .NET works.
              Hmm most of my projects have real time constraints,
              this one is in fact relativly simple, just a few hundred lines of code for
              the com port to file stuff.
              it was running in a few days from first loading the express c#
              Its true most people dont find the multi-threaded aspect so easy,
              wich just means I end up being more in demand for something I find relativly
              easy.
              IMHO, you should adjust your expectations to be more in line with the
              level of experience you have with .NET. I'm not saying .NET is
              problem-free, but it seems to me that you are spending too much time
              assuming that .NET can't do what you want or that it has fundamental
              problems, rather than exploring the possibility that you just have some
              things to learn before you can efficiently implement solutions in .NET.
              aha im a jump in the deep end kind of person,
              I had a few days to evaluate wich software package to use to do this,
              choices were c++ in mfc wich although I knew well would take a considerable
              amount of time,
              higher level data logging programs some wich were expensive and may not be
              flexible enough,
              matlab to do the graphical display,
              and would stil have to learn, or c# wich seemed a good opurtunity to learn,
              with available libraries it certainly seemed able to do the job.
              someone even sugested using spreadsheet.

              I think there is a great deal more about .NET than I need to know to do
              this.
              such as remote web stuff.
              a quote from microsoft - "no one person can even keep up with the all the
              changes"
              >I agree entiriely that its easier to do this sort of thing with much more
              >safety, (as in type safe)
              >underneath delegate is a function pointer hidden under heavy wrappers,
              >and it may produce less code wich maybe be easier to keep track of,
              >but for it to be easier overall im not convinced as yet.
              >
              It seems to me that in the context of .NET, delegates are exactly the
              right solution to the same problem function pointers address in C/C++. I
              have not seen delegates as being any more difficult to use than a function
              pointer, and they are type safe. What sort of "convincing " is it that you
              feel hasn't happened yet? It's not like you have to go to any extra work
              to use delegates; they are basically the same as function pointers and
              frankly, I find the syntax more sensible than that used for function
              pointers in C/C++.
              If you find it more sensible thats good for you,
              I see it as just a diferent way of doing it.
              yet something else to add to the learning curve from c++ to c#,
              but if your starting from scratch it maybe seems easier than learning the
              c++ way.
              yes it adds type safety wich is vital IMO.

              Il be convinced when ive found a neat way of doing this inter thread
              queueing,
              its early days yet, but so far its not been easy to find an easier way,
              and there seems to be a lot of confused people asking the same questions.
              although with lock{} its easy to write your own protected inter thread
              generic queue
              but you have to poll or wait, and if its that easy why isnt it part of the
              provided classes.
              some of the examples I initialy folowed seemed so incredibly complicated I
              cant understand why.

              ofc ive yet to get to the bottom of the confusion regarding the begininvoke
              issue.
              >It would be easier if they removed the need to write any of the
              >synchronizin g code yourself at least for the main culprits such as the UI
              >controls. although deadlock type issues are notoriously difficult to
              >ensure they dont happen, but then the new methods are not particularly
              >transparent and hence not easy to see such conflicts.
              >
              Deadlocks are always an issue, and I don't see how a language can prevent
              them. Perhaps one day, if someone figures out how to make a computer
              program provably correct, we'll get a compiler that does that. Until
              then, we're left with the problem that computer programs can be
              arbitrarily complex and preventing deadlocks isn't possible.
              With traditional way of thinking about flow of code yes I agree.
              As far as the cross-thread form execution issue goes, I agree that's a
              pain in the neck. It's unfortunate that rather than simply smoothing over
              that wrinkle, .NET simply propogates the pre-existing Win32 issue. But
              make no mistake...the issue is a Win32 issue, not one of .NET.
              I dont realy agree its a win32 issue, maybe im a bit rusty I havnt used raw
              win32 for a decade,
              so forgive me if im wrong but you could post a message to any control from
              any task and as long as the handle was still valid it went into the system
              and magically re apeared at the main message pump loop of the thread that
              created the control.
              ofc it was up to you to make sure any data you passed via pointers remained
              valid just for the duration.

              <http://msdn2.microsoft .com/en-us/library/ms644944.aspx>

              In fact you can post a message to change the main window text of another
              application.

              as far as I recall it was the advent of MFC with C++ wich cuased problems to
              the unwary due to mfc window control classes in particular using temporary
              data structures wich could get de-allocated when the main loop became idle.
              thus they were not always safe to access from outside the main thread.

              Colin =^.^=


              Comment

              • colin

                #8
                Re: sending events asynchronously

                "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
                news:op.tp4624s j8jd0ej@petes-computer.local. ..
                On Sun, 01 Apr 2007 16:51:35 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
                wrote:
                Likely you were reading something about using BeginInvoke on a delegate
                directly. If I recall correctly, that does execute the delegate on a
                thread pool thread.
                >
                But obviously, since when used with a form the whole point is to have the
                delegate run on the form's thread, when you use BeginInvoke on a form, the
                delegate must execute on the form's thread, not a thread pool thread. It
                wouldn't make sense any other way.
                Pete
                ah yes I re read that article and I now realise theres a diference in the
                invoke in the class for the control wich must obviously run it on the
                control class thread in order for it to work otherwise it would end up with
                a thread unsafe exception, compared to the general invoke, wich im not sure
                why it would run on a seperate thread as it claims to run on the main thread
                for the class wich is presumably the thread it was created with, but if it
                has no message loop pump how will it do it?

                ah thats it my brains given up ....

                wel im totaly safe using begininvoke now anyway ...
                heres my code for this, miles shorter than many examples ive seen...
                static public void safeSetText(Con trol cntrl, string s)

                {

                if (cntrl.InvokeRe quired)

                cntrl.BeginInvo ke(new MethodInvoker(d elegate() { safeSetText(cnt rl, s); }));

                else

                cntrl.Text = s;

                }

                Colin =^.^=


                Comment

                • Peter Duniho

                  #9
                  Re: sending events asynchronously

                  On Mon, 02 Apr 2007 05:37:09 -0700, colin <colin.rowe1@nt world.NOSPAM.co m
                  wrote:
                  [...]
                  wel im totaly safe using begininvoke now anyway ...
                  heres my code for this, miles shorter than many examples ive seen...
                  static public void safeSetText(Con trol cntrl, string s)
                  >
                  {
                  >
                  if (cntrl.InvokeRe quired)
                  >
                  cntrl.BeginInvo ke(new MethodInvoker(d elegate() { safeSetText(cnt rl, s);
                  }));
                  >
                  else
                  >
                  cntrl.Text = s;
                  >
                  }
                  You're following the standard convention suggested in the MSDN
                  documentation. However, I see no reason to check InvokeRequired. You
                  know it's required...just call BeginInvoke (for that matter, as far as I
                  know there is no real penalty for calling BeginInvoke from a thread on
                  which it's not required). This does, of course, require changing the
                  delegate: "delegate() { cntrl.Text = s; }".

                  Pete

                  Comment

                  • Peter Duniho

                    #10
                    Re: sending events asynchronously

                    On Mon, 02 Apr 2007 05:15:07 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
                    wrote:
                    Ah thats confusing if theres 2 ways its done. I found the article again
                    ..

                    >
                    its a bit long. I havnt re-read it as yet.
                    Yes, it is confusing. It's my opinion that this kind of overloading is a
                    bad idea. For an environment that purports to try to make things simple
                    and prevent the programmer from doing the wrong thing, it's an oddity that
                    they don't do a better job distinguishing between these two
                    related-but-fundamentally-different behaviors.
                    basicaly your saying you can put the functionaility of queing the updates
                    into the thread, I was hoping to avoid this functionality here,
                    for clarity as much as anything so its clear to see theres little to
                    hold it up.
                    I don't understand that comment. Your i/o thread cannot update any other
                    thread unless it somehow pushes that update to another thread. It can
                    either queue it or it can signal it and wait for the other thread to
                    process it. The latter is obviously not what you want, so you're left
                    with queuing.

                    I doubt that queuing by BeginInvoke is significantly different than
                    queuing by other means, especially when all you're doing is setting the
                    text of a control.
                    [...]
                    I think there is a great deal more about .NET than I need to know to do
                    this. such as remote web stuff.
                    a quote from microsoft - "no one person can even keep up with the all the
                    changes"
                    I'm not saying you need to learn everything about .NET before you use it.
                    I'm saying that you can't expect it to be as quick as advertised until you
                    at least learn the parts you're going to use.
                    [...]
                    >What sort of "convincing " is it that you
                    >feel hasn't happened yet? It's not like you have to go to any extra
                    >work
                    >to use delegates; they are basically the same as function pointers and
                    >frankly, I find the syntax more sensible than that used for function
                    >pointers in C/C++.
                    >
                    If you find it more sensible thats good for you,
                    I see it as just a diferent way of doing it.
                    yet something else to add to the learning curve from c++ to c#,
                    but if your starting from scratch it maybe seems easier than learning the
                    c++ way.
                    yes it adds type safety wich is vital IMO.
                    But again, it's not different from C/C++. There's no typedef in C#, so
                    the syntax is a little different. But the declaration of a delegate in C#
                    is almost exactly the same as that of a function pointer in C/C++, and
                    still results in a type being declared.

                    What do you see as different about the two that requires you to be
                    "convinced" that using delegates isn't any harder than function pointers
                    in C/C++?
                    [...]
                    >Deadlocks are always an issue, and I don't see how a language can
                    >prevent
                    >them. Perhaps one day, if someone figures out how to make a computer
                    >program provably correct, we'll get a compiler that does that. Until
                    >then, we're left with the problem that computer programs can be
                    >arbitrarily complex and preventing deadlocks isn't possible.
                    >
                    With traditional way of thinking about flow of code yes I agree.
                    If you have a non-traditional way of thinking about flow of code in which
                    you can prove the absence of possibility of deadlock, you should publish
                    your results. This is something computer scientists have been working on
                    for a long time without any positive results.
                    I dont realy agree its a win32 issue, maybe im a bit rusty I havnt used
                    raw win32 for a decade,
                    so forgive me if im wrong but you could post a message to any control
                    from any task and as long as the handle was still valid it went into the
                    system and magically re apeared at the main message pump loop of the
                    thread
                    that created the control.
                    Yes, you could. And still can. That's not a counter-example to the
                    cross-thread issue. For example, when you set the Text property of a
                    Control instance, you aren't posting a message. You're sending it.
                    SendMessage occurs on the same thread, bypassing the message queue.

                    This was illegal to do from a different thread in Win32 and it's still
                    illegal in .NET.
                    [...]
                    as far as I recall it was the advent of MFC with C++ wich cuased
                    problems to the unwary due to mfc window control classes in particular
                    using temporary data structures wich could get de-allocated when the
                    main loop became idle.
                    thus they were not always safe to access from outside the main thread.
                    This isn't an MFC issue, nor did MFC have the issue you describe above.
                    All direct access of windows has always been unreliable when done from a
                    thread other than the window's thread. PostMessage has always been the
                    required mechanism to access a window from a thread other than it's own
                    (well, for as long as threads have been in Windows anyway).

                    Pete

                    Comment

                    • colin

                      #11
                      Re: sending events asynchronously

                      "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
                      news:op.tp51fod 88jd0ej@petes-computer.local. ..
                      On Mon, 02 Apr 2007 05:37:09 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
                      wrote:
                      [...]
                      wel im totaly safe using begininvoke now anyway ...
                      heres my code for this, miles shorter than many examples ive seen...
                      static public void safeSetText(Con trol cntrl, string s)
                      >
                      {
                      >
                      if (cntrl.InvokeRe quired)
                      >
                      cntrl.BeginInvo ke(new MethodInvoker(d elegate() { safeSetText(cnt rl,
                      ); }));
                      >
                      else
                      >
                      cntrl.Text = s;
                      >
                      }
                      You're following the standard convention suggested in the MSDN
                      documentation. However, I see no reason to check InvokeRequired. You
                      know it's required...just call BeginInvoke (for that matter, as far as I
                      know there is no real penalty for calling BeginInvoke from a thread on
                      which it's not required). This does, of course, require changing the
                      delegate: "delegate() { cntrl.Text = s; }".

                      Pete

                      I did try that however the text didnt get updated, I'm not sure why,
                      I probably did something wrong somewhere else.
                      the test does alow the function to call itself and not be recursively
                      reentrant.

                      I pieced together that above code from various sources.

                      Colin =^.^=


                      Comment

                      • mirko

                        #12
                        Re: sending events asynchronously

                        I have solved COM port by using 3 threads. Read COM port data thread just
                        queues read data into some list, middle thread reads queued data and invokes
                        main UI thread.
                        If COM port is stopped, middle thread empties the list.
                        I have used just locks around queue list, and once Invoke. It all works as
                        it should, UI is always responsive, and read data callback thread is almost
                        'realtime'.


                        Comment

                        • colin

                          #13
                          Re: sending events asynchronously

                          "mirko" <mirko@gmail.co mwrote in message
                          news:euthrl$789 $1@ss408.t-com.hr...
                          >I have solved COM port by using 3 threads. Read COM port data thread just
                          >queues read data into some list, middle thread reads queued data and
                          >invokes main UI thread.
                          If COM port is stopped, middle thread empties the list.
                          I have used just locks around queue list, and once Invoke. It all works as
                          it should, UI is always responsive, and read data callback thread is
                          almost 'realtime'.
                          Yes thats pretty much how I did it initialy
                          I need to timestamp the data to the nearest tick.
                          save the timestamped data to disk,
                          then plot the data on a graph with lots of statistical procesing and 2 FFT
                          too.
                          it creates about 10mb/hour.
                          I used ReadLine with a timeout rather than callback,
                          its easier for a non technical person to read the flow of the code.

                          the com port for the bluesoleil bluetooth is rather icky.

                          I since decided to split the app in to two parts,
                          one just logs the data to disk in 1hour files,
                          the other just reads the files,
                          this way I can mess about with the number crunching without having to stop
                          the data loging process,
                          wich needs to run for several days.

                          It still keeps up with the incoming data as it shares the current file,
                          when its read all the other files and reads null from the current file
                          it just waits 1s before trying again,
                          moving to the next file at the change of the hour.
                          I didnt realise this would actualy work so well.

                          I use Control.Begin.I nvoke to stream parts of the data to different text
                          windows so you can see if the data coming in is sensible, or try and work
                          out whats gone wrong.

                          splitting it up also meant the huge garbage collections cuased by the number
                          crunching no longer affeted the com task,
                          it would cycle from 4mb->500mb lol!

                          Incidently if anyone can answer this very newbie question,
                          I cant find an obvious answer, I have a shared file for the two applications
                          but the express c# makes a copy of it,
                          is there a way of simply sharing it ?
                          or do I have to make it as a dll or object or is it assembly and export it ?

                          and what do people do when you have a function wich doesnt fit into a class,
                          but needs to be shared by 2 diferent apps as c# requires all functions to be
                          in a class,
                          I made a class called funcs for such functions just contains simple general
                          conversion functions,
                          usualy just a couple of lines, originaly static on the form class, such as
                          my safetext and scanf type equivalants.

                          Colin =^.^=


                          Comment

                          • colin

                            #14
                            Re: sending events asynchronously

                            "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
                            news:op.tp52edc n8jd0ej@petes-computer.local. ..
                            On Mon, 02 Apr 2007 05:15:07 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
                            wrote:
                            >
                            >Ah thats confusing if theres 2 ways its done. I found the article again
                            >..
                            >http://www.codeproject.com/csharp/As...Invocation.asp
                            >>
                            >its a bit long. I havnt re-read it as yet.
                            >
                            Yes, it is confusing. It's my opinion that this kind of overloading is a
                            bad idea. For an environment that purports to try to make things simple
                            and prevent the programmer from doing the wrong thing, it's an oddity that
                            they don't do a better job distinguishing between these two
                            related-but-fundamentally-different behaviors.
                            I did find it a bit confusing to say the least.
                            But if it was explained with enough detail but in a concise way
                            that is easy to find it wouldnt be a problem.
                            >[...]
                            >I think there is a great deal more about .NET than I need to know to do
                            >this. such as remote web stuff.
                            >a quote from microsoft - "no one person can even keep up with the all the
                            >changes"
                            >
                            I'm not saying you need to learn everything about .NET before you use it.
                            I'm saying that you can't expect it to be as quick as advertised until you
                            at least learn the parts you're going to use.
                            well im impatient lol cant help it !
                            well actually I didnt realy expect to write all the bits of code in 60
                            seconds each.
                            Im just pointing out the disparity between the ease of some parts and the
                            difficulty of other parts.
                            To my mind multi threading should be made as easy as adding a control,
                            although you can add a worker thread in 10 seconds,
                            it takes a great deal of time to find out how to get round the problem of
                            thread safe UI controls,
                            when it is actually quite easy to do, just takes a long time to get there.

                            I think the ability to make an app in 60 seconds from scratch just makes it
                            more frustrating when
                            other things take many days to find out how to do.

                            I remember how hard I found it to learn C initialy when I didnt know anyone
                            who knew it.
                            >[...]
                            But again, it's not different from C/C++. There's no typedef in C#, so
                            the syntax is a little different. But the declaration of a delegate in C#
                            is almost exactly the same as that of a function pointer in C/C++, and
                            still results in a type being declared.
                            >
                            What do you see as different about the two that requires you to be
                            "convinced" that using delegates isn't any harder than function pointers
                            in C/C++?
                            hmm we're talking about two different things here,
                            the syntax of the delegate/function pointer wich I agree c# is effectivly
                            easier becuase it is more powerfull.
                            it lets you make a delegate of a block of code.

                            then theres the other issue of how its used for inter thread purposes,
                            wich took a little while to grasp becuase its not so clear.
                            >[...]
                            >>Deadlocks are always an issue, and I don't see how a language can
                            >>prevent
                            >>them. Perhaps one day, if someone figures out how to make a computer
                            >>program provably correct, we'll get a compiler that does that. Until
                            >>then, we're left with the problem that computer programs can be
                            >>arbitrarily complex and preventing deadlocks isn't possible.
                            >>
                            >With traditional way of thinking about flow of code yes I agree.
                            >
                            If you have a non-traditional way of thinking about flow of code in which
                            you can prove the absence of possibility of deadlock, you should publish
                            your results. This is something computer scientists have been working on
                            for a long time without any positive results.
                            well I dont have anything new im sure,
                            but if you take the methodolgies such as state machines and data
                            transformations
                            one step further and instead of writing code wich does it all in one or more
                            threads,
                            you just have functions wich just do transformations or
                            functions wich just drive state machines,
                            where all the data being passed in and out is done through the top level
                            parameters.
                            a seperate body does all the data passing and thread to task assigning etc.

                            It should be easier to prove/avoid any deadlocks.

                            ofc this could easily be done with just a strict guidline in any language.
                            I did try to push a project I was working on in this direction,
                            for wich I had written a real time threading executive,
                            but most people seemed dumbfounded by the idea.
                            >I dont realy agree its a win32 issue, maybe im a bit rusty I havnt used
                            >raw win32 for a decade,
                            >so forgive me if im wrong but you could post a message to any control
                            >from any task and as long as the handle was still valid it went into the
                            >system and magically re apeared at the main message pump loop of the
                            >thread
                            >that created the control.
                            >
                            Yes, you could. And still can. That's not a counter-example to the
                            cross-thread issue. For example, when you set the Text property of a
                            Control instance, you aren't posting a message. You're sending it.
                            SendMessage occurs on the same thread, bypassing the message queue.
                            >
                            This was illegal to do from a different thread in Win32 and it's still
                            illegal in .NET.
                            >
                            >[...]
                            >as far as I recall it was the advent of MFC with C++ wich cuased
                            >problems to the unwary due to mfc window control classes in particular
                            >using temporary data structures wich could get de-allocated when the
                            >main loop became idle.
                            >thus they were not always safe to access from outside the main thread.
                            >
                            This isn't an MFC issue, nor did MFC have the issue you describe above.
                            All direct access of windows has always been unreliable when done from a
                            thread other than the window's thread. PostMessage has always been the
                            required mechanism to access a window from a thread other than it's own
                            (well, for as long as threads have been in Windows anyway).
                            hmm thought win32 SendMessage always ensured the function ran on the thread
                            for that control.
                            post mesage is the same exept it returns imediatly where as send waits for
                            the function to return;

                            with MFC though you tend to call the individual message proccessing function
                            directly therefore bypassing the thread switching, wich is probably more
                            efficient on the same thread, but is not safe from another thread.
                            the problem is there is then no nice wrapper around the method of sending
                            the set text message via windows.

                            however I now know BeginInvoke can easily provide that functionailty in c#.
                            instead of just complaing about non thread safe calls it could provide this
                            inside the control
                            or at least give
                            tel you tel you let you know tell you give more readily available help in
                            how to do it.
                            >
                            Pete
                            Colin =^.^=


                            Comment

                            • Peter Duniho

                              #15
                              Re: sending events asynchronously

                              On Tue, 03 Apr 2007 08:52:11 -0700, colin <colin.rowe1@nt world.NOSPAM.co m>
                              wrote:
                              >What do you see as different about the two that requires you to be
                              >"convinced" that using delegates isn't any harder than function pointers
                              >in C/C++?
                              >
                              hmm we're talking about two different things here,
                              the syntax of the delegate/function pointer wich I agree c# is effectivly
                              easier becuase it is more powerfull.
                              it lets you make a delegate of a block of code.
                              >
                              then theres the other issue of how its used for inter thread purposes,
                              wich took a little while to grasp becuase its not so clear.
                              I still don't understand. A delegate isn't any different than a function
                              pointer in that respect, except for the *additional* functionality .NET
                              can provide when using one. That is, a function pointer (or delegate) can
                              be used to call a function on the same thread, or it can be used to direct
                              a different thread to call that function. It just depends on how you use
                              it.

                              One thing .NET offers is more robust, type safe ways to pass a complete
                              function call to another thread for execution (in the form of
                              Invoke/BeginInvoke). But that's not something that delegates specifically
                              support...deleg ates just happen to be part of the mechanism, just as a
                              function pointer would be part of the mechanism when doing that in
                              C/C++ (there's no reason you couldn't define an API in C/C++ to include a
                              function pointer and a list of parameters to use in a call to that
                              function pointer).

                              It sounds to me as though what you're really finding hard to grasp is the
                              Invoke/BeginInvoke stuff, and not delegates.
                              [...]
                              >This isn't an MFC issue, nor did MFC have the issue you describe above.
                              >All direct access of windows has always been unreliable when done from a
                              >thread other than the window's thread. PostMessage has always been the
                              >required mechanism to access a window from a thread other than it's own
                              >(well, for as long as threads have been in Windows anyway).
                              >
                              hmm thought win32 SendMessage always ensured the function ran on the
                              thread for that control.
                              Sorry, you're right. SendMessage() also ensures that the right thread is
                              used. What I meant was that PostMessage is what you have to use if you
                              don't want to block on another thread.

                              The point here is that you need to use Invoke (SendMessage()) or
                              BeginInvoke (PostMessage()) for cross-thread access to a window, and this
                              has always been true. It's not a .NET thing, it's not an MFC thing, it's
                              a Win32 thing.
                              [...]
                              with MFC though you tend to call the individual message proccessing
                              function directly therefore bypassing the thread switching,
                              Which is, I believe, the same thing that happens in .NET. But neither MFC
                              nor .NET introduced that concept. Pure Win32 applications always had the
                              option of doing the same thing, and they always had the same limitations
                              doing so.
                              [...]
                              however I now know BeginInvoke can easily provide that functionailty in
                              c#. instead of just complaing about non thread safe calls it could
                              provide
                              this inside the control or at least give tel you tel you let you know
                              tell you give more readily available help in how to do it.
                              Well, for what it's worth, the first time I tried to access a control
                              cross-thread like that, I looked at the exception displayed, clicked on
                              the link that said "click here for more information" (paraphrased... I
                              don't recall the exact wording), and I got a very clear explanation in the
                              MSDN documentation showing me how to use Invoke to deal with the issue.

                              I don't know whether your development environment is set up to provide the
                              same information, but I can say for sure that at least in some situations
                              (ie the default situation), that information is readily available.

                              Pete

                              Comment

                              Working...