StrataFrame Forum

SampleDataInstallerClass -> cross-thread error...

http://forum.strataframe.net/Topic13684.aspx

By Ralph Rutschmann - 1/23/2008

Hi there,

maybe I'm doing something stupid, but I tried the SampleDataInstallerClass from the Example.zip for C#. I unpacked the examples to the projects directory and opened the solution with VS2005. Then I corrected the references to my new strataframe components on my machine and started debugging.

I tried the Pre-Build Dialogs, but as soon as I click on the combobox to choose the server, I get an exception in MDDeployMain.vb at

 '-- Clear the combo

cboSQLServer.Items.Clear()

telling me, there is a cross-thread call exeption.

Therefore I can't choose any server and have to stop debugging.

Any hint?

TIA and friendly greetings, Ralph

By StrataFrame Team - 1/24/2008

Could you show the code where you are creating and showing the MDDeployMain form? 

Are you calling .Show() on the form or .ShowDialog() on the form?

By Ralph Rutschmann - 1/24/2008

Hi Ben,

"I unpacked the examples to the projects directory and opened the solution with VS2005. Then I corrected the references to my new strataframe components on my machine and started debugging."

I used the CSharpDemos.exe examples from Microfour for StrataFrame - http://forum.strataframe.net/Topic5397-17-1.aspx without any changes other than to correct the references.

Can you reproduce the error with the example like it is?

TIA and friendly greetings, Ralph

By Trent L. Taylor - 1/27/2008

Ralph,

I ran the C# sample that gets installed with the framework (instead of the one from the forum) and did not have any issues.  The one from the forum was ultimately added to the install.  Click Start -> StrataFrame -> Samples -> C# -> Database Installer Sample.  Run this sample to see if you have the same issue.  I am not having any issues with the sample.  If you are running the installer class (not the standard part of the sample) through an installation, then you have to take this into account if you are executing the install on another thread by creating a delegate or a synchronization object (ISynchronizeInvoke).  But if you are just running the WinForms sample, then I cannot reproduce.  Any additional details would be helpful Smile

By Ralph Rutschmann - 2/3/2008

Hello Trent,

> I ran the C# sample that gets installed with the framework (instead of the one from the forum) and did not have any issues.  The one from the forum was ultimately added to the install.  Click Start -> StrataFrame -> Samples -> C# -> Database Installer Sample.  Run this sample to see if you have the same issue. <

Yes, I do. Unfortunately. I did exactly what you described:

I clicked on 'Pre-Build Dialogs', then 'Next' without touching anything else, after that I clicked on the little down arrow at the combobox for selecting an SQL Server.

At this point I get the following error message:

 'System.InvalidOperationException was unhandled by user code
  Message="Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement cboSQLServer erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."
  Source="System.Windows.Forms"
  StackTrace:
       bei System.Windows.Forms.Control.get_Handle()
       bei System.Windows.Forms.Control.SendMessage(Int32 msg, Int32 wparam, Int32 lparam)
       bei System.Windows.Forms.ComboBox.NativeClear()
       bei System.Windows.Forms.ComboBox.ObjectCollection.ClearInternal()
       bei System.Windows.Forms.ComboBox.ObjectCollection.Clear()
       bei MicroFour.StrataFrame.DBEngine.Deployment.MDDeployMain.LoadSQLServers()
       bei MicroFour.StrataFrame.DBEngine.Deployment.MDDeployMain.sqlWorker_DoWork(Object sender, DoWorkEventArgs e)
       bei System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
       bei System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)

Maybe there is something wrong with my machine?

TIA and friendly greetings,

Ralph


 

By Trent L. Taylor - 2/5/2008

Maybe there is something wrong with my machine?

It is funny that you mentioned this....you are getting a cross-thread violation, which we have run into an issue recently where one machine would get the error and not another.  The difference had to do with AMD dual cores and another machine with an Intel HyperThreading procesor.  Strange, but true.  I wonder if there is something along these lines going on here.  I will look to see if there is some other precaution that we could take to aid in preventing this.  Thanks for the info.

By Ralph Rutschmann - 2/5/2008

Hi Trent,

my machine is equipped with an AMD Athlon 64X2 Dual Core Processor 4200+ / 2,21GHz, 1,00 GB Ram.

Unfortunately I can't run a test against a machine equipped with Intel chipset and processor because I do not have one near around. Are you using Intel without that problem? Then my next machine will surely have Intel on board.

Thank you very much and friendly greetings,

Ralph

By Trent L. Taylor - 2/5/2008

Actually I am using an AMD X2 Dual Core 6400+ ... I will still look into the issue to see if there is something that can be done.  Thanks.
By Ralph Rutschmann - 6/27/2008

Hello Trent! Smile

Meanwhile I kicked off my old AMD equipment and own a brand new Intel machine now. BigGrin

I installed all completly new from the scratch, Windows XP Professional, VS 2008 and the newest StrataFrame-Beta.

Unfortunately the problem persists, even with the new machine. It seems not to have something to do with AMD or Intel.

So I took a look what MicroSoft does with the Backgroundworker, which should have something to do with the error. I saw, that the examples from MS avoid any access to the GUI, from inside the doWork-Method. I tried to modify the source code, but found that not a good idea, because I do not want to modify the code again and again with any new release of SF.

I decided to translate the DeployDialogs-MDDDeployMain to C# and to modify it to my needs, using as much of the framework as I could.

And guess what? Right, the problem went away! BigGrin

Here is, what I did (among others):

private void cboSQLServer_DropDown(object sender, EventArgs e)

{

if (!_ServersLoaded)

{

_ServersLoaded = true;

//-- Clear the combo

this.cboSQLServer.Items.Clear();

//-- Start the thread

this.sqlWorker.RunWorkerAsync();

}

}

private void sqlWorker_DoWork(object sender, DoWorkEventArgs e)

{

// Do not access the form's BackgroundWorker reference directly.

// Instead, use the reference provided by the sender parameter.

BackgroundWorker bw = sender as BackgroundWorker;

// Start the time-consuming operation.

// e.Result = TimeConsumingOperation(bw, arg);

this.LoadSQLServers(bw, e);

// If the operation was canceled by the user,

// set the DoWorkEventArgs.Cancel property to true.

if (bw.CancellationPending)

{

e.Cancel = true;

}

}

/// <summary>

/// Loads the available SQL servers into the combo box

/// </summary>

/// <remarks></remarks>

private void LoadSQLServers(BackgroundWorker bw, DoWorkEventArgs e)

{

//-- Show the wait window

bw.ReportProgress(1);

//-- Establish Locals

SQLServerSchema loSQL = new SQLServerSchema();

ArrayList list = new ArrayList();

//-- Cycle through all available servers

foreach (SQLServerInfo loSQLInfo in loSQL.LoadSQLServerList())

{

//-- Add the item

list.Add(loSQLInfo.Name);

}

e.Result = list;

}

private void sqlWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)

{

if (e.ProgressPercentage == 1)

{

this.opgWindows.Enabled = false;

this.opgSQL.Enabled = false;

this.cmdBack.Enabled = false;

this.cmdNext.Enabled = false;

//-- this.cmdCancel.Enabled = false;

this.myWaitwindow.ShowWaitWindow(Localization.RetrieveTextValue("waitWindTxt030"), Localization.RetrieveTextValue("waitWindTxt040"));

}

}

private void sqlWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

if (e.Cancelled)

{

this.myWaitwindow.HideWaitWindow();

// The user canceled the operation.

MessageBox.Show("Operation was canceled");

this._ServersLoaded = false;

this.opgWindows.Enabled = true;

this.opgSQL.Enabled = true;

this.cmdBack.Enabled = true;

this.cmdNext.Enabled = true;

this.cmdCancel.Enabled = true;

}

else if (e.Error != null)

{

// There was an error during the operation.

string msg = String.Format("An error occurred: {0}", e.Error.Message);

MessageBox.Show(msg);

}

else

{

// The operation completed normally.

ArrayList servers = (ArrayList)e.Result;

for (int i = 0; i < servers.Count; i++)

{

this.cboSQLServer.Items.Add(servers.ToArray().GetValue(i));

}

if (this.cboSQLServer.Items.Count > 0)

{

//-- Select the first item

this.cboSQLServer.SelectedIndex = 0;

}

this.myWaitwindow.HideWaitWindow();

this.opgWindows.Enabled = false;

this.opgSQL.Enabled = false;

this.cmdBack.Enabled = true;

this.cmdNext.Enabled = true;

//-- this.cmdCancel.Enabled = true;

}

}

private void cmdCancel_Click(object sender, EventArgs e)

{

if (this.sqlWorker.IsBusy)

{

// Cancel the asynchronous operation.

this.sqlWorker.CancelAsync();

this.cmdCancel.Enabled = false;

}

else

{

try

{

if (_Migrator != null)

{

_Migrator.CancelConversionThread();

_Migrator.Dispose();

}

}

catch (Exception)

{

throw;

}

finally

{

this.DialogResult = DialogResult.Abort;

this.Close();

}

}

}

Maybe you can have a look at it and use it for the framework? OK, you will have to translate it to VB.NET, but this will surely not be a problem for you and this way you can shift my code to a much better one. Smile

Friendly greetings,

Ralph

By Trent L. Taylor - 6/27/2008

I am glad that you got it working.  I am unsure why your environment would act differently.  I looked through the code to ensure that there was no cross-thread violations...and I did not see any.  However, we are about to rework this dialog anyway, so I will be sure to take this into account!

Thanks for your information and efforts!!!!

By Ralph Rutschmann - 6/27/2008

Hello Trent,

I am unsure why your environment would act differently.

sometimes it worked as expected, somtimes I got a cross-thread error.

I looked through the code to ensure that there was no cross-thread violations...and I did not see any.

Accessing the combobox from inside the DoWork-Method is causing the error. The combobox is an element instantiated outside the DoWork thread of the BackgroundWorker and therefore lies at another thread, I guess. I don't know why it is working sometimes, but I don't know at all why Windows is working sometimes, or not... Wink

However, we are about to rework this dialog anyway, so I will be sure to take this into account!

Thank you very much, this will be great! Smile

But could you localization issues also take into account? It would save me (and other international customers too) tons of work...

Thank you very much and friendly greetings,

Ralph

By Trent L. Taylor - 6/28/2008

But could you localization issues also take into account? It would save me (and other international customers too) tons of work...

That would probably be a good idea.  Just to make sure that you are aware...you can create your own deployment dialogs right now as we speak.  In fact, the framework comes with a sample showing how to do this so you can create your own deployment environment for an install or whatever need you have there.  This is what we do for our medical software as well as the SF installation.  This is just a thought so you could move forward without having to wait on me Smile

By Ralph Rutschmann - 6/28/2008

Hi Trent!

That would probably be a good idea.  Just to make sure that you are aware...

Yes, Trent. I'm aware and that's really cool. Cool

But it would be even cooler, not to have to do that.

Please don't get me wrong, SF is a great framework and I love it. I tried a few others and found SF seems to fit my needs best, especially the data deployment tool. This tool makes SF a real time saver when installing data for applications. Unfortunately this really important tool is not localized, which causes me to 'create my own deployment environment for an install'. It would be really great not to have to do that. I hope I can put my own development environment into a trash-can some time soon... Wink

Thank you very much and friendly greetings,

Ralph

By Ralph Rutschmann - 8/3/2008

Hello,

sorry for asking this again, but it crashes on two of my machines (Intel and AMD) even with the newest beta:

''' <summary>

''' Loads the available SQL servers into the combo box

''' </summary>

''' <remarks></remarks>

Private Sub LoadSQLServers()

'-- Establish Locals

Dim loSQL As New SQLServerSchema()

Dim loSQLInfo As SQLServerInfo

'-- Show the wait window

sqlWorker.ReportProgress(1)

'-- Clear the combo

cboSQLServer.Items.Clear()                          <-- possibly cross thread error

'-- Cycle through all available servers

For Each loSQLInfo In loSQL.LoadSQLServerList()

'-- Add the item

cboSQLServer.Items.Add(loSQLInfo.Name)             <-- possibly cross thread error

Next

'-- Select the first item

If cboSQLServer.Items.Count > 0 Then

cboSQLServer.SelectedIndex = 0                    <-- possibly cross thread error

End If

End Sub

 This is what I found at http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Note:

You must be careful not to manipulate any user-interface objects in your DoWork event handler.

Seems to me like manipulating the combobox is causing the problem. A little bit above in this thread I sent you already what could be done to avoid the problem. It would be very nice if you would think about to fix it in some of the next betas or at least the next final of StrataFrame.

Thank you very much! :-)

Ralph

By Trent L. Taylor - 8/3/2008

Ralph,

It seems to me that you already know what to do Wink  This sample was written a long time ago prior to the cross-thread issue check within VB.NET as well as C#.  We are very familiar with how threads and events work and what must be done in regards to talking to the main thread via a delegate.  Thanks for letting us know that there is a potential issue in a sample.  We will look at this prior to finalizing the 1.6.6 build.

Just FYI, the database migrator class is 100% thread safe and is something that is used extensively on a daily basis.  So there is not an issue within the framework in this regard.  But in any case, we will add this to the "to-look-at" list before the final release.

By Ralph Rutschmann - 8/3/2008

Dear Trent,

It seems to me that you already know what to do Wink

yes, I know already what to do. But could it actually be the reason to buy a framework to have it to fix by my own? I don't think so, Trent. Sorry. I couldn't imagine that the reason to buy a framework also could be to write the built-in dialogs and functions by myself to have them functional, translated or something else. If I would think so, I would write my own framework, wouldn't I? ;-)

This sample was written a long time ago prior to the cross-thread issue check within VB.NET as well as C#.

The posted code is not out of an old example, I took it directly from the newest beta-source code dated July, 24. 2008 directly downloaded from my download area at StrataFrame. Sorry, Trent, would you please be so kind and have a look at it?

We are very familiar with how threads and events work and what must be done in regards to talking to the main thread via a delegate.

So I think you could easily fix the problem, If you like to do.

Thanks for letting us know that there is a potential issue in a sample.

Again, I don't talk about a sample here. I talk about the source of the framework.

Please have a look at MMDeployMain.vb, Private Sup LoadSQLServers(), which is called from inside the sqlWorker.DoWork()-Method and because of this runs inside the thread, manipulating a GUI-element outside the thread. Sorry, I don't know how to express myself better in english, but I hope you understand what I mean?

We will look at this prior to finalizing the 1.6.6 build.

That's great, I'm sure there was only a misunderstanding. :-)

Just FYI, the database migrator class is 100% thread safe and is something that is used extensively on a daily basis.

OK, Trent. Than I have only hallucinations and the errors I sent to you are only in my imagination, I must be delirious. Sorry for annoying you with my incompetence and ignorance. I beg your pardon for my mistake. All right?

Let me tell you something, an old german people wisdom: 'If you can not find any mushroom in a wood, that means not that there are no mushrooms!'. Maybe there is something similar in english.

This old wisdom get's very funny if you interchange 'mushroom' with 'bug' and 'wood' with 'software'... ;-)

So there is not an issue within the framework in this regard.

If you think so... But I can't help me, I get errors...

But in any case, we will add this to the "to-look-at" list before the final release.

Please, Trent, not at the 'to-look-at' list. At the 'urgent-to-fix' list, please! :-)

Thank you very much and friendly greetings!

Sincerely yours,

Ralph

By Trent L. Taylor - 8/4/2008

Ralph,

There is absolutely no need for caustic or "smart" remarks.  We always strive to provide excellent support and if there is an issue within the framework...we have NO issue addressing it and getting a fix out there.  In fact, making the change once I actually found what you were looking at took less than 30 seconds!  So there has been far more emotion, frustration, and strain wasting on this forum thread than ever was placed towards comin up with a resolution.

You keep telling me that it is not the sample, but if you will look at this thread, your subject reads, "SampleDataInstallerClass."  So if you weren't referring to a sample...then it would be a good idea to post where the error actually is that you are running into versus encrypting the message Wink

First of all, the problem that you are having is not in the DatabaseMigrator class anyway!  Which as I mentioned, is 100% thread safe.  After re-reading your post several times and trying to understand where you were actually having the problem, the issue was in the MDDeployDialog class (again not the SampleDataInstallerClass or the DatabaseMigrator class as you had mentioned).

Also, in the future, please provide the class or a stack trace versus trying to just explain the issue which will take all of the emotion and frustration out of the formula as well as provide static facts which can lead to a resolution.

Finally, you and I had discussed through email this dialog and I informed you that this dialog will be made obsolete in a future release as this dialog will be re-worked to follow themes and to be localized.  This is why we provide the ability to create your own deployment dialogs using the DatabaseMigrator sample as well as provide samples.  The DatabaseMigrator class is where all of the work is done...not the MDDeployDialog, which only collects SQL information and allows a package file to be selected, which in turn uses the DatabaseMigrator class.  If you had looked at the DatabaseMigrator sample which comes with the framework, you would have seen that you could have created your own deployment dialogs very quickly and easily as this MDDeployDialog is not really something that was ever intended to be used largely in the field as it requires the end-user to have to know too much.  Most of this should be masked from them preventing deployment issues.

At any rate, I have already spent far more energy than was ever necessary on a 30 second fix...it will be in the next posted update.

By Ralph Rutschmann - 8/4/2008

Trent,

OK, I see your point and where I did the mistake. I used the old thread with the old problem and wrote in the message, posted yesterday @ 12:11:45 PM: 'sorry for asking this again, but it crashes on two of my machines (Intel and AMD) even with the newest beta:'

Do you really mean the 'newest beta' could be an old example? Then I would have to think hard about my english...

And I took the SampleDataInstallerClass while I'm not using my first framework and I really don't want to be asked over and over again if I can reproduce the errors with the examples coming with a framework.

As mentioned, english is not my native language. But I do my very best to express myself and to improve my english. Sorry if my best is not worth a penny, but it's all I have.

So let's get back to the issue:

I really hate it to be told there is no problem when my machines are crashing over and over again, reproducible at the same point with a cross-thread-error. And I really hate it to post an easy fix (OK, it was a fix in C# and surely not the best way to fix the problem), but only to hear that 'there is no problem at all, but thanks for your efforts'. More than that I hate to be told over and over again something like: 'We are very familiar with how threads and events work and what must be done in regards to talking to the main thread via a delegate' while my machines are crashing with cross thread errors.

Or even better: '...you can create your own deployment dialogs right now as we speak.' And I got told that not only for dialogs. If I would plan to write my own database-deployment-dialogs, my own localization and so on among other things I got told I could easily do by myself, I would not know why I should spend money for a framework.

Maybe the subject of the thread is not a subject which describes correctly the kind of the problem or where it lies. But if you had have a look at the posted code two steps earlier in this thread you would have seen that it can't be code out of an old example, but that it is actually source code of the newest source code of the framework. Or can you show me any old example with a method 'Private Sub LoadSQLServers()' which is not identical with the source code of the framework like it was at July, 24?

Again, I beg your pardon if I expressed myself wrong or took the wrong thread or subject to get you knowing about that the problem persists even with the newest beta.

You wrote me above in the thread: 'I ran the C# sample that gets installed with the framework (instead of the one from the forum) and did not have any issues.' One or two messages later in the thread you wrote me: '...you are getting a cross-thread violation, which we have run into an issue recently where one machine would get the error and not another.'

So what do I have to think now? Is there a problem which you can reproduce or not? Am I stupid? Am I hallucinating problems when I see my machine crashing? Ah, I should stop smoking that damned stuff...

What do you think what I posted for what Microsoft tells about accessing the GUI while on a thread? To annoying you while looking at my machine crashing with a long known cross-thread-error I told you a long time ago in many messages?

And that's not the only problem I am reporting only to get told something like: 'There is no problem, the framework is used for apps running in production environments world wide without any issue'.

Am I dreaming? Should I believe that I am actually the only one at the whole world with a sometimes wired browse dialog? Is it really true that I have to do all I can do to get you to reproduce an error which takes only three mouse clicks to reproduce? Do you know what you wrote me the first time I told you about the wired browse dialog throu email?

Yes, something like: There is no problem at all, the browse dialog is used by many, many people out in the field without any issue.

Dear Trent, please tell me what do I have to do not to annoying you but to get token serious when reporting bugs?

Do you remember what kind of fight I had to fight to get you to understand what I mean at the newly introduced Search Field Identifier? I gave you an example how Microsoft it does in VS to get you understand the need of numbering the new identifier and you wrote me: 'Well, the reason we don't do that by default is for backward compatibility..and core logic.'

What? Backward compatibility for a newly introduced identifier nobody could have ever used? What backward compatibility? I didn't understand. I really didn't understand. I do not understand 'til now. Do you? Can you tell me what kind of backward compatibility the Search Field Identifier should have? I can't imagine of anything...

And core logic? What kind of core logic? I think I need an example...

But at the good end you wrote: 'I think that I get where you are coming from.  I agree that it would be easier to increment the name for subsequent column names.  This would be a farily easy thing to implement in a future build.  I will add it to the list.'

Thanks god, Trent got me right, I thought. :-)

But why took it so long time an so hard efforts to get him to that idea that it 'would be easier to increment the name'?

Did it not even VFP this way? Numbering identifier automatic?

Trent, I think there is a lot going wrong with our conversation. It seems I'm not able to communicate in english. I should stop it, I think. Maybe I should stop programming at all. It seems someone spoke a spell at me to find any bug, but not to be taken serious when reporting.

OK, Trent, let me beg your pardon again if I did or wrote something stupid. But please understand that I'm tiered of writing 4 or 5 messages to get you things done that take 'a 30 second fix'

At any rate, I have already spent far more energy than was ever necessary on a 30 second fix...

You took the words right out of my mouth, my words, dear Trent, my words...

...it will be in the next posted update.

This thread was started by me in january. Can you tell me why it took so long time and so many messages when it is only about a 30 second fix?

Ralph

By Dustin Taylor - 8/4/2008

Trent is unavailable at the moment, so just to answer your most pertinent question: It took this long to solve the problem because it took this long for us to recognize the problem to which you were referring. We mistakenly believed you were speaking about a problem with a sample, not core functionality. Regardless of whether that is a language-barrier related miscomunication, a fault in your explanation, or a fault in our undersating of that explanation, that is why it took this long.

We make every effort to offer prompt and precise support via this forum. As soon as we recognized this particular issue as a core problem, it was diagnosed and fixed ("within 30 seconds", in Trent's words.)

Time is precious for both you and for us, so I will not waste either of our time by continuing the argument any further than this: the problem has been recognized and resolved. It will be posted in the next release. We appreciate your continued business and, regardless of where the fault lies in the delay for this issue, regret that it took so long to resolve.