Wireless Communication Library Support Forum

Frameworks => Bluetooth Framework => Topic started by: alexey_gusev on June 01, 2009, 07:21:30 AM

Title: OPPClient and multiple threads
Post by: alexey_gusev on June 01, 2009, 07:21:30 AM
Hello,

I'm using several wclOPPClient objects to send files to the phone. The whole procedure is asynchronous. At one place I BeginInvoke() some starting method, in this method I create an object that encapsulate an array of wclOPPClient (say, WCLSender) and call WCLSender .SendFiles():

            sender = new WCLSender(arrBtAddr, arrFiles, senderWaitTime);
            eventFileSending = new EventFileSending(sender.SendFiles);
            eventFileSending.BeginInvoke(new AsyncCallback(OnFileSendingFinish), eventFileSending);

In completion method I do some post-processing of the files sent (or rejected, or timed out).

That's where I have a question. I've defined an array of ManualResetEvent in my WCLSender class, so they may be Set() at various stages. In sender.SendFiles(), I call Connect() on all wclOPPClient objects. Then I want to just wait in SendFiles() until all handlers signal either error or completion (by setting manual event). If I wait for events to be signalled on the same thread where I call Connect(), my OnConnect callbacks are never called. If I call wclOPPClient.Connect() on the different thread and wait for the same events in SendFiles() - I do hit the callbacks. Threads must continue looping, otherwise callbacks are not called.

Am I completely wrong here with such design or missing something obvious?
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 01, 2009, 10:42:13 AM
Hello,

You are doing all correct except one thing. Your thread must have message loop to be "alive" to get events. The MFC edition includes the sample for that. I am sure, the same can be implemented in .NET too.
The other idea is do not use threads (like ProximitySender implemented).
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 01, 2009, 10:50:02 AM
OK, I see, so if I wait on the event, I then block the current thread (and as a result no incoming messages).
Is it hard to implement it in such way that one can initiate the sending (calling Connect() ) and then wait on event right after the call, ie to be based on event handlers rather than messages?
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 01, 2009, 10:55:18 AM
Hi,

Yes, you are right, when you wait on event you block the messaging.
Unfortunatly it is impossible because internal stacks implementation. But I am still wondered why you use threads or asynchronious library :) It is easy to implement all in one thread and handle all the things without problems.
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 01, 2009, 11:03:46 AM
well, I'd love to avoid using threads, believe me :)
unfortunately I've inherited the C# application which is complex and multithreaded, with MANY BeginInvoke() calls, so I needed some firm grounds. At some point discovery and sending were implemented as separate console applications which reported back to the main one via pipes  :D . I've moved their code into the main app recently.

So the main idea is to kick off the discovery, then, if user wanted to send files, invoke sending part and finally post-process the files to ensure e.g. that they won't be resent again. I admit it may be redesigned to have all processed in the main thread without any threads, but I'd like to get to the dead end first :)
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 01, 2009, 11:18:14 AM
Ok, I see

I'll try to create a C# sample with using WCL in threads today or tomorrow and post it here then. Will it be ok?
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 01, 2009, 11:20:13 AM
absolutely! thanks a lot for that
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 01, 2009, 12:59:35 PM
some unrelated question: how safe is to call Terminate() for wclOPPClient when it doesn't send anything? is it enough to call just Disconnect() to be sure it cleans all up and closes gracefully?
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 01, 2009, 01:57:45 PM
Yes, if there is nothing sending - call Disconnect(). Teminate sends some data to the device and it must be called only when sending in progress. Also you can terminate sending with simple Disconnect call. Terminate just terminates current sending but does not close the connection.
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 04, 2009, 12:16:54 PM
Hi,

I promised the sample. It is more or less finished and will be included in next release which is planned for ths weekend. Is it OK?
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 04, 2009, 12:21:46 PM
yeah, that's great, thanks
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 08, 2009, 05:40:38 PM
hello Mike,

is multithreaded sample included into new release? if yes, please let me know where to look

BR,
Alex
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 08, 2009, 05:54:11 PM
Hi,

yes, it is included in the package. It should be at the same folder where other samples are.
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 08, 2009, 05:57:34 PM
could you tell me the folder name please?
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 08, 2009, 06:11:33 PM
OPPThreads
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 08, 2009, 06:15:03 PM
oops, I will reinstall it to ensure, because I don't see it right now anywhere
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 08, 2009, 06:22:30 PM
hmm, that's either just me or the zip file doesn't contain that folder at all. I've reinstalled the exe (WCL_Personal_NET.exe) and don't see anything like *thread* in any demo folders
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 08, 2009, 10:54:15 PM
Ooops. My mistake. I am really sorry. I have created the samples but didn't modify installer script to add samples to Setup. Will fix it tomorrow and reupload, or upload a sample here.
Title: Re: OPPClient and multiple threads
Post by: alexey_gusev on June 08, 2009, 10:58:58 PM
ok, no probs :)

while we're on it, could you please fix small typo in TIMEOUT error returned from wclErrors.GetErrorMesage() ? right now it reads "Timout" (ie  "e" is missing)

Thanks,
Alex
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on June 09, 2009, 01:09:22 AM
Fixed, thanks :)
Title: Re: OPPClient and multiple threads
Post by: Cuningan on June 13, 2009, 03:16:39 PM
Hello Mike and Alexey.

Please notify here when the package with the example will be terminated because i am interested in it.
Title: Re: OPPClient and multiple threads
Post by: ehartwell on June 25, 2009, 06:59:22 PM
I'd also love to see the sample.

Thanks to this post, I just finished debugging the same problem in a WPF .NET application. I;m using the Disconnected event triggers a retry timer that keeps retrying the connection until the device is back in range. The wclClient object was originally created in the UI thread.

When I used System.Timers.Timer to call Connect(), the device was connecting, but the Connected event was never being raised. I finally changed the code to use System.Windows.Threading.DisapatchTimer, which runs in the UI thread instead of its own worker thread, and now the Connected event is raised and caught.

The corresponding UI thread timer for Windows Forms applications is System.Windows.Forms.Timer.
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on July 02, 2009, 01:53:02 PM
Here is very simple demo app. It processes only 2 events (OnConnect and OnDisconnect) but I think you will get the idea.

[attachment deleted by admin]
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on July 03, 2009, 12:23:07 AM
Updated sample. Now it sends the file. How to use:

Click "Select" to select the file. Clieck "Discover" to find the devices. Select device and click "Send". Wait when "Disconnected" appears. Do not click "Send" when already sending.

Very simple but easy to unerstand sample.

[attachment deleted by admin]
Title: Re: OPPClient and multiple threads
Post by: ehartwell on March 04, 2010, 03:39:51 PM
I have a C#/WPF application using WCL quite successfully. We found that WCL events are missed unless WCL runs in WPF's UI thread. Up to now this has meant we need to use System.Windows.Threading.DispatchTimer and not System.Timers.Timer.

We've just found an issue, where Bluetooth send and receive apparently blocks while the application is busy. We've already moved as much of the processing code into background threads as we can; what's left is the unavoidable WPF overhead for things like DataView updates.

The OPPThread sample works great (thanks!), but at its core it has an Application.DoEvents() loop.  In its wisdom, Microsoft decided DoEvents really *is* evil (http://www.dacris.com/blog/2009/11/18/DoEventsReallyIsEvil.aspx), and designed WPF without a DoEvents API.

Since WPF does all its UI handling on a single thread, it doesn't let you monitor Windows messages on a background thread. There are a few workarounds posted on the web, but they all come with scary warnings about bad effects and application instability.

So, my questions are:


Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on March 04, 2010, 03:43:22 PM
Hi,

1. Yes of course. Run it in separate thread with separate windows message loop.
2. It may be.
Title: Re: OPPClient and multiple threads
Post by: ehartwell on March 04, 2010, 03:47:57 PM
Wow! Talk about quick response! I'll see what I can do, but as I said, WPF doesn't want to share its Windows message loop, so we may have to resort to interop. I'll let you know what happens.
Title: Re: OPPClient and multiple threads
Post by: Mike Petrichenko on March 04, 2010, 03:53:19 PM
Yes, that may need some work. unfortunatly there is no other good way to synchronize different threads except using windows messages. And threads must be synchronized to be sure that WCL events will fire in the same thread which called method. It is not WCL limitation but it was developed so to make it working good with .NET, VCL, COM and MFC. As you may know .NET does not allow to fire (catch) events with different threads (as well as VCL/MFC).

The other idea it to try move some job from your main thread to separate one and have WCL in main thread.

P.S. That's why I do not like .NET. UI development is great and simple, but as you start making something specified it become to be a nightmare.