I've done some reading on this at MSDN and around the web and now more confused than before.
I am working with a vb.net windows form application and wish to use multiple threads (but not multiple apartments).
Does this mean I need to set MTAThread attribute on the program entry point or not?
Some sources seem to indicate yes, some say a windows form app should be STA because of the COM objects, some say MTA will be set automatically when threads are created, some not... thoroughly confused now.
If I do need to set it can I do this without disabling the app framework and creating amodule to hold a Public Sub Main()?
I would consider puttin the TCPListener in a class object, with properties that the calling form can access, this class can have events your form can listen for and pass data to the UI - delegates maybe needed. The tasks could be class objects too and there can be a List(Of Task) Since they are class objects too they can now raise events which will be heard by it's owner that is listening for them. Any task that is being handled on a seperate thread will require delegates even with event raising.
Related
I am trying to write a code to check previous instance of the application in vb.net, my requirement is that application should prevent for same user and it should allow for different user who wants to access through remote parellel 2x client..Any one please help me on this...Thanks
If you are using VB.Net, You should definetly look into WindowsFormsApplicationBase class, shipped as part of .NET framework.
There is a property (IsSingleInstance) specifically designed to provide single instance behavior to the application.
You can even receive notifications through StartupNextInstance or the counterpart OnStartupNextInstance method when another instance of the application tries to run.
I forgot to mention that My.Application already is an object of the WindowsFormsApplicationBase type (at least in VB.NET WinForms applications).
UPDATE:
Currently, to take advantage of this stuff from a VB.NET project you have to follow these steps:
Edit project properties.
Enable "Make single instance application".
Click "View Application Events".
(optionally) Implement StartupNextInstance event handler.
Say your code receives an instance from an external source, and you had no control over how the instance was created. The instance does not implement INotifyPropertyChanged. Is there an adapter you can pass it to, as in:
var adapter = new ChangeNotifierAdapter( instance );
such that the adapter implements INotifyPropertyChanged and will thereafter raise its PropertyChanged event for all property changes of instance?
If you can guarantee that all changes to the instance will go via your wrapper, then you can use a proxy - either a dynamic one or one generated at design time (nb: if you have to still expose the concrete class rather than an interface it'll have to be a dynamic proxy).
If that's not true (or even if it is, but changes to one property affect the value of another) then the only way to achieve this is via polling. The wrapper has to periodically poll all the properties of the object, determine which have changed and raise events accordingly. This is messy, and can be a serious battery drain on mobile devices.
Both suck of course. Mapping to an object that does implement it is generally a better solution.
I made a simple PasteBin demo example of what my code looks like: http://pastebin.com/GpDhPRVm
My actual Process object is extremely complex that includes adding collections of Tasks, Documents, Workflows, etc into a Process object and setting properties through methods, etc.
My PasteBin example is as simple as I can make it to show where things break down. Including the Process object in the CreateNewProcess method in my service (shown in code below), allows the service user to automatically "see" the Process object, properties and enumerators in their instance on the client side.
<ServiceContract()>
Public Interface ICreateProcess
<OperationContract()>
Sub CreateNewProcess(ByVal newprocess As Process)
End Interface
However, it does not allow them to use any of the methods like the 'AddTask' method (shown in PasteBin example) and it also doesn't expose the Task or TaskCollection objects. Even if I decorate the methods with DataContract, OperationContract, etc they still are not visible to the client service.
This is my major issue: I need the client service to be able to fully "build" the Process object and then pass it in to the CreateNewProcess method.
Another small note: (to avoid comments asking me about it) is that I made sure that all of my properties are simple types that are interoperable since this needs to be able to work for Java - not just .NET clients.
Ok, I figured it out with a little help from a buddy of mine.
Can't use methods at all outside the .svc service class; only properties, enums and sub objects will translate down to the client. (I figured this)
Then, instead of using a Collection, you have to use a generic List type.
So, instead of this:
Public Tasks As New TaskCollection() 'where TaskCollection inherits from Collection
I needed to do this:
Public Tasks As List(Of Task)
And the client will just have to build their own array of Tasks and assign it to the t.Tasks property.
This works like a charm now: http://pastebin.com/rt8HwsXY
When using a Silverlight-enabled WCF service, where is the best place to instantiate the service and to call the CloseAsync() method?
Should you say, instantiate an instance each time you need to make a call to the service, or is it better to just instantiate an instance as a variable of the UserControl that will be making the calls?
Then, where is it better to call the CloseAsync method? Should you call it in each of the "someServiceCall_completed" event methods? Or, if created as a variable of the UserControl class, is there a single place to call it? Like a Dispose method, or something equivalent for the UserControl class.
Thanks,
Jeff
You're better off just having an instance variable for the service. Creating and destroying the service for each call creates a lot of unnecessary overhead. Just create the variable and call the methods, no need to open it since this will be done automatically as of beta 2 (see section #5).
As for close, whether you try to close it for clean up probably depends on how your app is structured. If when the UserControl is closed the whole app is shutting down (the user closed the browser) then you probably don't need to explicitly close it since everything will get cleaned up when the Silverlight host closes. However, if you're creating lots of these user control and closing them while keeping the app open then you might want to create some kind of close method on your control that would clean up by calling CloseAsync.
If all the user controls use the same service, then you could just create a single service wrapper class that is used by all the controls that would handle calling the service. This would keep you from having to close the services when the controls unload as well.
In the case of 2 parallel event handlers in your SL client, you can do the following approach to make sure only one gets invoked:
Assume, we have a global client variable, App.Client, which is being used by everything in the app.
Now, control 1 needs to react on MyOperationCompleted, as does control 2.
Each control uses the eventhandler like this:
...
{
App.Client.MyOperationCompleted += Client_MyOperationCompleted;
App.Client.MyOperationAsync(...);
}
void Client_MyOperationCompleted(object sender, MyOperationCompletedEventArgs e)
{
App.Client.MyOperationCompleted -= Client_MyOperationCompleted;
}
So if you subscribe to the event in one case, as soon as it returns, you remove the subscription to this event. If if you always stick to this, it's quite unlikely (however not impossible) that other controls react to the event. Note that this approach is not 100% concurrency safe. I'm still trying to come up with a really safe method for doing this. But it sure helps.
We have a third party dll that is used in our web service hosted in IIS6. The problem is that once this dll is loaded into memory, the exception AccessViolationException gets thrown if a thread different then the one that created it tries to execute any code within the dll. The worker process is multi threaded and each call to the web service will get a random thread from the pool. We tried to unload it from memory and reload it each time we needed it, but I guess only the front end is .Net and the rest is unmanaged so it never actually gets completely unloaded from memory. We are using VB and .Net 2.0. Any suggestions?
(Response to Rob Walker)
We thought about creating a new thread and using it to call the dll, but how do we make the thread sit and wait for calls? How do you delegate the call to the thread without having the Dispatcher class supplied by .Net 3.0? Creating a hidden form and putting it in a message loop might work. And then we could call the Invoke() method of the form. But I can see many problems occurring if we create a form inside an IIS hosted web service.
I have read about a class in .net 3.0 called Dispatcher that allows you to put a thread in a loop and then call the method Invoke() using a delegate to execute a method using the thread. But this solution will not work if you cannot update to .Net 3.0. Another solution would be to host the third party dll in another application on the server and use some form of Remoting to access it. But you may still have a problem with the Remoting because it behaves similar to IIS and will also pick a random thread to execute the code . To get around this, you could put a wrapper around the dll and use it to delegate the calls to the UI thread by using the Invoke() method of the form.
I think you need to look at using a wrapper thread that handles all calls to the DLL, and deals with the serialization.
This thread is outside of the managed thread pool, so you control its lifetime. But even this would not be foolproof unless you can prevent IIS from restarting the app domain your web service is in.
You also need to worry about what happens when two web service requests come in at the same time. Is each call into the DLL standalone, or do you have to group together all the calls associated with a single web service request before allowing any other request to be serviced?
You could create a service that hosts the extra DLL. Via remoting you access the service, this will dispatch the calls the the thread that manages the DLL.
This way you have control over the thread that calls the DLL, and over the lifetime of the thread.
I'm a bit rusty, but you might try wrapping calls to the DLL in a single threaded apartment COM object. This would ensure that all calls go through the COM object's windows messaging thread. I think you would have to register the component in a server application within Component Services to do this.
Can you run the dll inside different threads as different instances? Like thread1 creates an instance of this third party dll, and thread2 also does, but as long as thread1 doesn't try to use thread2's instance it won't throw that exception? If thats the case, .Net never unloads any code once its loaded, if you load an assembly and then remove it, it still sits in that application pool. If you can create more than one instance at a time, you could load it up in a separate app pool you control per a request, then unload the app pool. Performance might drop though.