Multi-threading issue + DataReady already open - winforms

We are developing a WinForms application in my company.
We are facing a threading issue.
A thread TH is started in the runtime beginning.
TH reads regularly a record from a table TB.
A DataTable is used for retrieving the record.
The DataTable is filled by a SqlDataAdapter.
The DataTable is disposed as soon as an object is created modeling the retrieved record.
A DataGridView in a Form could be filled with data from TB during the runtime.
The DataGridView must be filled on the main thread that is the thread where user controls are created.
But an exception is thrown when filling a DataTable.
The exception message adverts that a DataReader is already open on the Command used to retrieve records from TB.
I have tried without success to surround a statement executed on TH in a lock block.
I am not used to threading programmation so I do not know what I can do to prevent the exception.
Any help will be greatly appreciated.

I have got useful information from this web page : http://msdn.microsoft.com/en-us/library/haa3afyz(v=vs.80).aspx
The web page contains this information :
Note that while a DataReader is open, the Connection is in use
exclusively by that DataReader. You cannot execute any commands for
the Connection, including creating another DataReader, until the
original DataReader is closed.
In my context :
DataReaders used respectively on the main thread and thread TH execute a select command for the same connection.
The SqlDataAdapter.Fill method probably uses an internal DataReader.
A try to execute the Fill method can be made on the main thread while another call to the Fill method is not yet finished on thread TH.

Related

Bonitasoft Bonita Newbie: Showing and editing data entered by user before

I'm new to Bonitasoft Bonita Studio.
I want to design a form with UI Designer with three input boxes: name, surname, order.
The input shall be thrown to another pool via a message. In the second pool, there is a "catch message event". The data that was entered by the user should be shown in another task/form in this pool and it should be possible to edit the inputs.
That should be very easy, but I can't get this mini-project to work. Could anybody help me please?
Main question is: How can I show the data that was entered before in a new form?
I use a business data model and have a business variable for each pool. I try to use "throw message" and "receive message" to pass the business variable data from one pool to the other pool, but unfortunately i can't use the data from first poll in the second pool.
Could anybody help me please?
Pool 1: Business variable called "bestellung"
Pool 2: Business variable called "kundenbestellung"
In pool 1: throw message event. message variable "nachrichteninhalt" takes value of "bestellung"
in pool 2: receive message event. business variable "kundenbestellung" takes valoue of message variable "nachrichteninhalt"
in pool 2: task to show data of "kundenbestellung" (i tried it with normal Bonita-function and with REST-API, but nothing works)
Screenshots: (sorry, I'm not allowed to include pictures directly into this topic as I'm to new in this forum)
Diagram
Pool 1 variable
Pool 1 message throw event
Pool 2 variable
Pool 2 Receive message event
Pool 2 show data task
Pool 2 show data task form

Exception: The Calling thread cannot access this object because a different thread owns it

I'm converting a UI from windows forms to WPF. I'm getting the following exception "The Calling thread cannot access this object because a different thread owns it" whenever I try to call anything on this new WPF window I created.
I referred stack overflow and many websites to find out that I should use Dispatcher.CheckAccess() or somethings similar to dispatcher and check access. I tried many such things
This is one of the things that I have used
Private Delegate Sub ShowSkinInvoked()
If (Dispatcher.CheckAccess()) Then
Me.Show()
Else
Dim d As ShowSkinInvoked = New ShowSkinInvoked(AddressOf ShowSkin)
Dispatcher.Invoke(d)
End If
This has removed the exception and while debugging the error is gone but it freezes the application and I cannot do anything other than terminate it. It doesn't even show the window after "Me.Show".
Also, if I compile the program and then make the calling module use this compiled exe by specifying path to exe then for some reason it works perfect.
If this sounds confusing then what I mean is, I have multiple forms. If I call the code in module A to load and display module B then it gives me the exception but if I call the code in module A to run the compiled exe of module B then it runs perfectly.
Any suggestions?
When WPF creates a user interface it created a thread that is responsible for handling all the user interaction events and scheduling the rendering. This is called the dispatcher thread. Many of the objects that it creates are sub classes of DispatcherObject.
You can't call methods on a DispatcherObject from threads other then the Dispatcher thread that created them. The reasons why are complicated but relate to COM interop.
When you are in a Buttons click event you are running on dispatcher thread.
If you are coming from another thread you must get your work to be performed on the dispatcher thread. It can typically be found by accessing the static current dispatcher Dispatcher.CurrentDispatcher, unless your creating multiple dispatcher threads.
However I would suggest explaining your problem in terms of what work your trying to do with regards to having one form show ui on another. There are multiple ways like an EventAggregator to communicate between ui that might be more appropriate.

Update DataGridView from thread

So I have simple DataGridView with rows containing name, surname, status.
Now I have another sub which is starting 5 threads. Each thread will do it's job and update DGV accordingly to its result.
Problem is that to run thread accessing update method for DGV I had to set:
_namethread= New Thread(AddressOf namethread)
_namethread.IsBackground = True
_namethread.SetApartmentState(ApartmentState.STA)
With set STA I end up without errors BUT DGV isn't updated and nothing happens. It looks like call for update method simple is skipping (on update method I do have Application.DoEvents just in case)
There is also another thing. I want to use threads to update database, refresh DGV for other tables, etc.
Thing is that I know how to access textboxes from threads (by delegating method) but I have no idea how to do it with accessing database by SQL query or even DHV to show progress.
Maybe I should use event riser or something else.
How are you doing this normally :) ?
If I'm correct if I would create custom Event, I could call it from thread ?
Is this DoEvents working like other subs (so it would go step by step through all events rised, so for example would update 6 records in database ?)
Something like a queue ?
I just need to know in which direction I should go with threads (as I want do to very heavily multithreaded application)
I think I solved this issue by using delegates.

get handles count associated to a kernel object (win 32 application)

I'm developing a simple win32 application with two processes sharing memory through a file mapping. At a certain point in the second process, I want to check if the other process has already closed the handle associated to the file mapping.
Is there a Windows function to retrieve the number of handles associated to my shared memory???
Thanks in advance for any help...
There's nothing in the API to do that. If you want to know when the other process has finished its work, create a manual reset event with CreateEventEx, and have the other process set the event when its work is done. The first process can use one of the wait functions to query the status of the event.

"The calling thread must be STA, because many UI components require this." Error in WPF?

I am creating a xps document as below.
Assembly assembly = Assembly.GetExecutingAssembly();
//read embedded xpsDocument file
Stream helpStream = assembly.GetManifestResourceStream(resourceNameOfContext);
if (helpStream != null)
{
Package package = Package.Open(helpStream);
string inMemoryPackageName = "memorystream://" + topicName + ".xps";
Uri packageUri = new Uri(inMemoryPackageName);
//Add package to PackageStore
PackageStore.AddPackage(packageUri, package);
docXps = new XpsDocument(package, CompressionOption.Maximum, inMemoryPackageName);
}
return docXps;
When i am trying to get docXps.GetFixedDocumentSequence();
I am getting the above error. Can anyone help?
Thanks,
Your problem has nothing to do with the code surrounding the creation or use of the XPS document. It has everything to do with what thread you are running under.
You will receive the The calling thread must be STA, because many UI components require this error whenever any of the following are attempted on a MTA thread:
You construct any object derived from FrameworkElement (including Controls and Panels)
You construct any object derived from BitmapEffect
You construct any object derived from TextComposition
You construct any object derived from HwndSource
You access the current InputManager
You access the primary KeyboardDevice, StylusDevice, or TabletDevice
You attempt to change the focus on a FrameworkContentElement
You provide mouse, keyboard or IME input to any control that accepts text input
You make WPF content visible or update its layout
You manipulate the visual tree in such a way as to cause a re-evaluation for rendering
Several other changes, mostly having to do with display and input
For example, I received this error last year when I tried to deserialize some XAML that contained <Button> and other WPF objects from within a WCF service. The problem was simple to solve: I just switch to a STA thread to do the processing.
Obviously most work with XPS documents will trigger one or more of the above conditions. In your case I suspect that GetFixedDocumentSequence ends up using TextComposition or one of its subclasses.
No doubt the my solution of switching to a STA thread will also work for you, but first you need to figure out how your code that works with XpsDocuments is getting executed run from a MTA thread. Normally any code from from the GUI (eg a button press) is automatically run in a STA thread.
Is it possible that your code that manipulates XPS Documents may be being executed without a GUI? From a user-created thread? From a WCF service or a web service? From an ASPX page? Track that down and you'll probably find your solution.
If that doesn't work, let us know the details of the path through which GetFixedDocumentSequence is called, so we can diagnose it. The directly surrounding code isn't nearly as important as the call stack and how it is originally being invoked. If it is hard to explain you probably should add a call stack to prevent misunderstandings and help us diagnose the problem further, or tell you how to start a STA thread in your particular situation.
Is your code trying to access the xps doc from a background thread? If this is the case, you'll want to use the dispatcher. Info on that here.
If this doesn't help, could you post the code where you're actually calling GetFixedDocumentSequence()?

Resources