|
Maybe it is not so curious, but it is to me at least.
I have a system.timers.timer declared and set up and then the code executes the final line in the routine is ProcessDuplicateMessage.
In the ProcessDuplicateMessage routine I get this error:
System.InvalidOperationException was unhandled by user code
Message="Cross-thread operation not valid: Control 'lblReviewValue' accessed from a thread other than the thread it was created on."
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.set_WindowText(String value)
at System.Windows.Forms.Control.set_Text(String value)
at System.Windows.Forms.Label.set_Text(String value)
at ....FImportMsgProcess.ProcessDuplicateMessage() in C:\....\FImportMsgProcess.vb:line 41
at ....FImportMsgProcess.FormLoadComplete(Object sender, ElapsedEventArgs e) in C:\....\FImportMsgProcess.vb:line 134
at System.Timers.Timer.MyTimerCallback(Object state)
Now obviously this is something to do with the timer, which I assume is running in a different thread, but my question is:
How do I return the process to the thread for the form before calling the next routine.
If I remove the system.timers.timer and add a forms.timer I don't get the problem.
Just curious really since I have cured the immediate problem by using a forms.timer instead and I would like to know for another occasion.
|
|
|
|
|
You're correct about the System.Timers.Timer "firing" your code on a seperate thread. Docs on the Timer class are here[^]
You also cannot access UI controls from any other thread other than the thread that created the control, i.e.: the UI (or startup) thread. A good article on the hows and whys of this can be found here[^].
|
|
|
|
|
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
When I find a good article, I run with it.
|
|
|
|
|
I'll try and create some more then...
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Thanks Dave, and of course Luc for the article.
|
|
|
|
|
You're welcome.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I have just rewritten some shared code to put it into namespaces so that it will be easier to find.
After adding this stuff to namespaces now my code does not work because I am not importing the namespaces on each form.
I know that you can import namespaces for the entire project in properties but I am wondering is this something that will hurt performance.
Even if it will not hurt performance is there another way that I can only import the namespaces into the code files that actually use them because I am not wanting them at project level because while that will make my code work.., it defeats the reason for doing this to begin with which is to narrow the amount of things showing up in intellisense.
I hope that is clear enough if not please just tell me.
Thanks,
Brian
Humble Programmer
|
|
|
|
|
You need to import namespaces only in the files where you use their types.
Example: Having one source file doing networking does not make all files need an Import System.Net
And even then, you don't HAVE to import anything, you could also use the fully qualified name.
Eample: Dim form as System.Windows.Forms.Form would not require an Import System.Windows.Forms
In general I do not recommend you do this though.
So, if you have moved types to another namespace, watch the compiler error messages, and fix them, in the files the error messages point you to.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I understand that you should not share every file.
Is there an easy way than going through and fixing each imports manually?
Humble Programmer
|
|
|
|
|
No. You fix the files the compiler complains about, there is no overall approach, if there were, it would to a large extent defeat the purpose of the namespace concept.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I guess I was just hoping there would be something like the window where you can show unused references.
oh Well thank you for your time luc.
Brian
Humble Programmer
|
|
|
|
|
I believe there is a feature where you can tell Visual to remove unused imports. Which would be a file operation (so you order it for each source file, one by one), and not very valuable. I don't have any details about it, I've never used it.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
As far as the performance question, importing extra namespaces at the project level *may* affect the performance of the compiler *slightly*, but it will not affect the runtime performance of your program/library at all. By the time the IL is run, all calls are performed against fully resolved types/functions regardless of your imports.
|
|
|
|
|
I am trying to get the changes made to a datagrid to be saved back to the database.
Every time i update i get a concurrency error.
Any help would be greatly welcome.
Dave
Friend Sub UpdateDatabase()
frm.Cursor = Cursors.WaitCursor
Dim isGood As Boolean = True
If DataServer.IsConnLost Then
If DataServer.IsConnBack = False Then Exit Sub
DataServer.IsConnLost = False
End If
Dim sqlString As String = "SELECT * FROM " & frm.dgData.DataMember
Using conn As New SqlConnection(DataServer.SQLConn)
Using adapt As New SqlDataAdapter(sqlString, conn)
Using cmdbuilder As New SqlCommandBuilder(adapt)
adapt.TableMappings.Add("Table", frm.dgData.DataMember)
Try
adapt.Update(CType(frm.dgData.DataSource, DataSet).Tables(frm.dgData.DataMember).GetChanges)
Catch ex As Exception
WriteEventLog("Unknown EX " & Me.GetType.Name & vbCrLf & ex.Message & vbCrLf & ex.StackTrace, , EventLogEntryType.Error, , 58)
End Try
End Using
End Using
End Using
ChangeDataBase()
frm.Cursor = Cursors.Default
End Sub
|
|
|
|
|
Hi everybody,
I'm a bit stuck reading RGB pixel data from a filestream into a bitmap correctly. The file format (dpx) is a 10-bit RGB format, and as long as I stay with the original proportions (scaleFactor = 1) I can read from the file and get a perfect bitmap - everything including the colors is just fine.
Now, for performance reasons I want to read lesser data from the file, e.g. read only every 16th pixel (scaleFactor 4). The basic idea seems to work, but the funy result is that the bitmap is sqeezed and multiplied in width . E.g. with a scaleFactor of 4 I get the same bmp multiplied 4 times in width into the same picture box...
I don't find out what's wrong with the idea or my implementation in the code? Could anybody please help me out of this maze?
Thanks a lot!
Mick
Here's my code:
int scaleFactor = 2;
imageWidth = this.DPXWidth / scaleFactor;
imageHeight = this.DPXHeight / scaleFactor;
fs.Position = this.DPXOffset;
byte[] PixelArray;
Bitmap bmp;
int stridefactor;
int imgSize = (int)(fs.Length - fs.Position) / (scaleFactor * scaleFactor);
if (this.DPXDescriptor == 50)
{
imagePixelFormat = PixelFormat.Format24bppRgb;
bmp = new Bitmap(imageWidth, imageHeight , imagePixelFormat);
stridefactor = 3;
PixelArray = new byte[(int) imgSize / 4 * 3 ];
int step = scaleFactor * scaleFactor;
for (int i = 0; i <= (PixelArray.Length - 1); i += 3)
{
UInt32 mybuff = SwapDWORD(br.ReadUInt32());
PixelArray[i] = (byte)((mybuff & 0xffc) >> 4);
PixelArray[i + 1] = (byte)((mybuff & 0x3ffffc) >> 14);
PixelArray[i + 2] = (byte)((mybuff & 0xfffffffc) >> 24);
if (scaleFactor > 1)
{
for (int j = 1; j <= step - 1; j += 1)
{
br.ReadUInt32();
}
}
}
}
fs.Close();
br = null;
fs = null;
BitmapData bmpData = bmp.LockBits(new Rectangle(new Point(0), bmp.Size), ImageLockMode.WriteOnly, imagePixelFormat);
IntPtr p = bmpData.Scan0;
System.Runtime.InteropServices.Marshal.Copy(PixelArray, 0, p, imageWidth * stridefactor * imageHeight);
bmp.UnlockBits(bmpData);
return bmp;
|
|
|
|
|
After a very quick scan of your code I can see nothing obvious.
However, it has occurred to me that you might have the SizeMode property of the PictureBox set inappropriately, PictureBoxSizeMode.StretchImage maybe?
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
Why do programmers often confuse Halloween and Christmas?
Because 31 Oct = 25 Dec.
|
|
|
|
|
Hi Henry,
thank you for having a look. You were right about the SizeMode property, but unfortunately changing it (to anything) doesn't help. I still have the same picture multiple times, multiplied and also width-wise squeezed by the scalefactor I set.
I'm quite sure it's a silly little thing that I don't see, and which is most likely part of the code.
|
|
|
|
|
Is scale factor not working the other way round? i.e. 4 is 4xZoomed In so 4 x wider
What about setting it to 0.25 (ie. 4 x zoom out)
|
|
|
|
|
Hi Dave,
I guess from the thought I followed I should have named the variable "reduceFactor". Anyway changing it to 0.5 doesn't help. In the current approach, when reading UInt32s from the file I read one pixel and skip (scaleFactor^2 - 1) pixels. How many would I skip with 0.5 ? I'm pretty sure it would end in an even bigger mess. Thank you still, but maybe you see anything else in the code?
|
|
|
|
|
Hi Michael,
IMO your scaling is fundamentally flawed. Assuming you have good code for scale factor 1; now if you want to sub-sample (say scale factor 2), then:
- you should process only some of the input lines;
- of the lines you keep, you should process some of the pixels;
- of the lines you ignore, you should skip all pixels.
So you can't handle it with a skip loop that skips scalefactor^2 pixels, you really need two skip loops, a horizontal one and a vertical one. And you need to count rows and columns.
Also, I didn't like your total image size as calculated from the file length. Finally, depending on the exact pixel format of your input, the code may need adjusting; e.g. I think you may have to read the actual stride from the file.
PS: you may have put this in the wrong forum, it looked like C# code to me.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Hi Luc,
my God you're right - I'm in the wrong forum! C# code it's a big exception for me, so I just didn't realize... Nevertheless I'm afraid that it's the language-independent basic principle where I'm mislead in this piece of code - and I honestly have to agree to your term "fundamentally flawed".
Unfortunately I can't read the actual stride from the file - it doesn't contain such a value. From the file's format (each RGB pixel has 30 bits in 4 Bytes) I think I can assume a stride of 4 * width. Right?
First I'll try your approach of reading line by line!
|
|
|
|
|
yep, if no stride information is available, you should assume each row strictly follows the previous one (which isn't necessarily so in an in-memory .NET image, as pixels might be aligned to a higher power-of-2 multiple).
Now even with consecutive rows, you must reset your rescaling counter for each row, otherwise it would go wrong if say your scale factor is 2 and the image width is odd rather than even.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Hi Luc,
thanks to your hints and with a good portion of stamina I finally made it
In case you're intersted - and also for others who read the the record - here's the way how I read the raw data now (sorry... still C# )... and btw dpxStride is simply the original pictures' width * 4, assuming the best.
imagePixelFormat = PixelFormat.Format24bppRgb;
bmp = new Bitmap(imageWidth, imageHeight, imagePixelFormat);
PixelArray = new byte[(int)imageWidth * imageHeight * bmpStride];
for (int r = 0; r <= this.DPXHeight - 1; r += scaleFactor)
{
long readPosition = r * dpxStride;
fs.Position = this.DPXOffset + readPosition;
long writePosition = readPosition / scaleFactor / scaleFactor / rawStride * bmpStride;
int c = 0;
for (c = 0; c <= (this.DPXWidth * bmpStride / scaleFactor) - 1; c += 3)
{
UInt32 mybuff = SwapDWORD(br.ReadUInt32());
PixelArray[writePosition + c] = (byte)((mybuff & 0xffc) >> 4);
PixelArray[writePosition + c + 1] = (byte)((mybuff & 0x3ffffc) >> 14);
PixelArray[writePosition + c + 2] = (byte)((mybuff & 0xfffffffc) >> 24);
for (int j = 1; j <= scaleFactor - 1; j += 1)
{
br.ReadUInt32();
}
}
} If you have another good idea on it (maybe regarding better coding style) I'll appreciate. On the other hand they say 'Never change a running system'
Thanks
Michael
|
|
|
|
|
Hi Michael,
yes that looks like a valid attempt, or at least pretty close to it.
I'm a bit worried about you having three stride variables; and I'm not convinced the heavy writePosition calculation is warranted (aren't you generating all the result pixels simply in their logical order anyway?).
Here are some more ideas:
1.
your subsampling assumes an integer scale; you could also apply fractional sampling, which basically means when you want row Z with a scalefactor of T/N, you calculate Zscaled=Z*T/N, which, rounded to some integer value, tells you which row to use. Similar for horizontal scaling.
If you want to do the fast scan direction efficiently, you may want to study the Bresenham algorithm.
2.
Rather than skipping pixels one by one, as your final for loop does, I would consider this:
- read an entire row at a time, asking the stream to fill an uint array with the correct number of bytes;
- use a pointer inside the uint array to access pixels or colorcomponents.
The net result is the last for loop becomes a simple addition.
3.
Assuming you want maximum performance, I would also consider:
- smashing the byte swap logic, i.e. copying the SwapDWORD code into your current snippet (manual inlining);
- removing all multiplications from the loops; either do them once, beforehand; or use a running sum, as appropriate.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|