Windows Forms Project with Threading - vb.net

I have read a LOT of material about Windows Form projects not supporting MTA. I get it. However, I also have read about Background worker, async/await and BeginInvoke use with such solutions. This and this are just a couple of examples. Here's one that even uses MSMQ. Some of the examples I have reviewed go way back to VB6 days.
I need to augment a Windows Form project with code to interact with a vendor service via API calls that could benefit from async capability. This being 2014, what is the best way to approach this? I use VB NET and have VS 2010 for my development.
Ideally, I would like to create a class library with the logic to interact with the vendor and just return the results to my Windows Form project. Can that be done?

The fact that MTA is not supported doesn't mean that you can't use multiple threads. The MTA model is just one way to use multiple threads, but because it's difficult to implement objects for that model, Windows Form uses the STA model instead.
The important effect of this is just that it means that the main thread in the application takes care of everything that has to do with the user interface. You can start as many threads as you like/need, but whenever anything from those threads needs to be displayed in the user interface, they have to use the Invoke method to let that update be done in the main thread.
There are already asynchronous method in the framework, for example the BeginRead and BeginWrite methods in the System.IO.FileStream class. You can have a look at those for some hints on how asynchronous methods are used in the framework.
If the API is synchronous, you would make asynchronous methods by simply starting a new thread that does the API call and then executes a callback method when it is done. As it's that thread that is waiting for the response, the call doesn't occupy the main thread.

Related

VB.Net, specify a thread for BackgroundWorker to use?

This is far-fetched I know but I have to ask. Is there a way to specify the thread that a BackgroundWorker instance is to use? Or at least some way to force it onto another specific thread (whose reference I have). I have a large project that makes use of BackgroundWorker, and I have just recently started using some in-house FRAMEWORK (I have to) that uses Thread instead, and the two seem not be happy with each other (I know the reason but I can not fix it as it is in the framework whose guts I can modify) that is why I ask this question, before I spend days converting my project to use FRAMEWORKS Threading functions.
You might be able to derive from the BackgroundWorker class as it's not sealed and override the methods for RunWorkerAsync etc. Would be painful and easy to introduce bugs, but that would give you the ability to kick off the DoWork event onto your in house thread framework.

Is the Singleton Pattern suitable for a VB.Net tray app without the Application Framework?

I'm creating a Windows Tray App which doesn't use the Application Framework. The startup object is a module sub, which makes calls to a class to create the app icon directly in the tray without opening any forms.
I've just started reading about the Singleton Pattern, with the intention of making the app single-instance. This seems to be the way it should be done, but...appearance and reality are not the same. What looks good may not be.
Is singleton the best way to make a tray app single-instance?
Are there other ways that should be considered?
Are there any common problems that arise when developing with these ways?
There seems to be a fundamental misunderstanding of what a singleton is that is leading you astray. A singleton is a class that enforces that there can only ever be one instance of the class throughout the lifetime of an application.
The singleton pattern doesn't apply to applications as a whole.
If you require that the application restrict itself to only allow one instance to be running at any given time then, what I have done in the past is to have your app check the running processes on the computer as soon as it starts. If it finds any that have the same name as what your app is called then the second instance stops itself.
The flaw with this approach is that there is nothing to say that some external application can't have the same name as your application(however unlikely that may be)
I've never really looked into it beyond that so I can't comment on any other viable options.

Method for replacing INVOKE

Is there a way around using the Invoke and InvokeRequired methods for objects which were created in other threads? Is there a method which is more direct and less memory intensive? Perhaps a state machine or thread controls?
Am I wasting my time worrying about this method's resource usage?
I'm using this invoke method: http://tech.xster.net/tips/invoke-ui-changes-across-threads-on-vb-net/
I'm using VB.NET in VS 2012
This strongly fits my doctor's usual advice: "if it hurts then don't do it".
There are several .NET patterns that emphasize keeping the threaded code separate from code that needs to run on the UI. BackgroundWorker has been available for a long time, note how its ProgressChanged and RunWorkerCompleted events run on the UI thread. Good place to update UI without having to invoke yourself.
The .NET 4 Task class hands you the TaskScheduler.FromCurrentSynchronizationContext() method. Which is a good way to chain a task that runs on the UI thread, pretty specifically intended to update the UI with the results of previous tasks that run asynchronously. VS2012 provides yet another weapon with the Async and Await keywords. All good ways to avoid writing the code you don't want to write.

VB.NET Circular Dependency / Duplex Communication between Projects

I have 2 projects
UI
Functionality
UI references Functionality to call specific functions. Functionality needs to call certain functions that operate UI. This is what I mean by Duplex communication. Is there any way to do this without causing circular dependency?
Should there be 1 main project which simply does all the calling acting as a "wrapper" between UI and Functionality?
Your "functionality" (business layer) piece probably shouldn't be calling the "ui" puiece. In fact it should need to know anything about it since that is the point of separating your project into layers to begin with. If you had to change your UI layer to something different, web based, windows form, mobile, etc this should always be independent.
You probably want UI to call Functionality, not the other way around. That's best practice. You can use an event mechanism or callbacks if you need to observe the Functionality project and respond to events.
UI calling Functionality and Functionality calling UI is inadvertently going to be a circular reference. You want to avoid that.

How to access COM objects from different apartment models?

I have a multi-threaded C++Builder GUI app, which communicates with a third-party app via COM.
I need to call methods of the COM object from several threads, and I'm protecting access with a mutex. Apparently, the main GUI thread must use STA model, but my worker threads need to use MTA. The COM object is constructed in an MTA thread.
Everything works fine except access to the COM object from the GUI thread, due to the MTA/STA mismatch.
I've read a bit about marshalling, but haven't tried to implement it, because the examples I've seen seem to require different access semantics depending the the current apartment model, and I really would like to have code that (from a programmer's POV) doesn't care about the current apartment model.
So, is there an idiomatic way to write COM code that operates on the 'same' object, but can be called from both STA and MTA threads?
Put the COM object interface into the Global Interface Table and let the GIT handle the marshalling for you. When any thread requests the COM interface, the GIT checks the calling apartment and will provide a direct pointer or a suitable proxy accordingly. Your code won't know the difference (or care), just use the returned interface normally as needed.
This is documented on MSDN:
Accessing Interfaces Across Apartments