|
Within the same AppDomain, access to static members is serialized so they are automatically thread-safe.
What is the exception that is thrown. Saying "my application crashes" is hardly specific enough to provide you with any decent amount of help.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
This may be obvious, but does that mean that static members act like critical sections in that access from another thread will be automatically blocked until the current thread exits that static method? If so, that's great to know. If possible, could you point me to a link where I can read more about it?
Thanks again for both answers,
-Peter
|
|
|
|
|
Actually, upon looking for your documentation I found this to not be true. I was told this once a long time ago in the managed newsgroups. Guess I shouldn't take things for granted, huh?
In that case, use the C# lock keyword (which uses a Monitor when you compile) or a Mutex to synchronize access.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Oh, and using string concatenation to create SQL expressions is a terribly BAD idea. All I have to do is pass 0 OR 1=1; DROP TABLE HillFile -- and bye bye HillFile data. I could do a lot worse, too, depending on the content which I could easily discover since most RDBMS expose schema information that can be queried, like SQL Server and Access.
Use parameterized queries. See the SqlCommand.Parameters property documentation[^], as well as the SqlParameter class documentation[^] for details and examples. This also could be the reason you're getting an exception, if you're passing in string data that includes quotes anywhere. Using parameterized commands aleviates this problem, as well as avoiding SQL injection attacks. If you're getting a SqlException , which is most like the problem.
And, BTW, if your applications "crashes" because of an exception thrown, you really need to handle exceptions better. There is no reason - short of a catastrphic failure and in order to protect data - that an application should crash. Always validate your data and handle problem areas with try-catch blocks.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
thanks for the tips. In my new stuff I always use the .Parameter rather than sql because of the issues you mention. Also, I do need to better handle my errors so I know what the conditon was on the thread crashes.
|
|
|
|
|
Can someone suggest the different ways to persist/share temporary data across classes in a multi-tier WinForm Application?
For example, assume that I have a Data Structure/Class that holds [connection related data] and another one that holds [user preferences data]. Where can I store –temporarly- this data so I can readily access it from any object in the application with ease.
The following are the methods that I am aware of:
1. Share data through static methods... Bad idea because it is Public.
2. Share using AppDommain.CurrentDomain’s SetData and GetData methods.
Thanks in advance!
|
|
|
|
|
DaMagicMaster wrote:
The following are the methods that I am aware of:
1. Share data through static methods... Bad idea because it is Public.
2. Share using AppDommain.CurrentDomain’s SetData and GetData methods.
Both ways are public. Statics are only the same within the same AppDomain . Any other application or code in another AppDomain won't see the same thing.
Using approach #1, however, they don't have to be data. If your application is in one assembly, you can declare the members as internal , but this defeats the purpose since for a single assembly internal is the same as public . In .NET 2.0 you can also use the InternalsVisibleToAttribute in your assembly to name which other assemblies can see internals. Currently you can use code access security to allow only certain assemblies to access those members, for instance by their public key token (since all assemblies should be signed, and you typically sign all your organization's assemblies - or at least assemblies for a particular product - with the same key pair). See the StrongNameIdentityPermissionAttribute in the .NET Framework SDK for details.
In a N-tier application, that data must also be serializable, so don't forget that. An assembly on one machine couldn't access the data on another without that data being marshaled, which requires the data to be serializable in .NET. If you're using the .NET Framework features - such as .NET Remoting[^], this means attributing your classes and structures with the SerializableAttribute and optionally implementing ISerializable to control the serialization of an object. If you create your own mechanism - which isn't recommended between two managed applications, but may be necessary if supporting legacy code either on the client or server - then you must make sure you marshal your data in other ways. Windows drag-n-drop and the clipboard have a few different ways of marshaling data, from global memory to streams and more.
Between managed code, however, I highly recommend .NET Remoting[^]. It's like Web Services on steroids, and allows you to serialize to binary formats and use different wire formats (like TCP instead of HTTP, which is - by nature - unidirectional). You can even define your own formatters and channels, as well as other sinks which act on the data in a non-specific way (a great example of Aspect-Oriented Programming, or AOP).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Cool; I did not know that static is limited to same application domain!
Are there any other ways to share data between objects in the same winforms assembly/application?
For instance, in web forms, we can use session or application objects to share and persist data across webpages without having to pass these data from one page to the other.... how about WinForms, are there better mechanisim to persist/share data beside storing the data in appDomain or static classes?
Thanks
|
|
|
|
|
You can store small amounts of data in TLS (Thread Local Storage) using obvious members of the Thread class, but - again - this is only recommended for small amounts of data. When you alloc TLS for a thread, all threads are alloc'd that amount (at least from what I understand of the native APIs that these methods encapsulate).
Passing references to the data or storing in statics is your best option, though. There are many, many more ways like using ContextBoundObject objects to provide the same data to all AppDomains within a process (and even passing them to remote AppDomains) to locking them in global memory (not recommended except for P/Invoke or COM interop) using the Marshal class. I recommend reading through the C# Language specification as well as the .NET Framework SDK both available online at http://msdn.microsoft.com/library[^] for more ideas and information.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks... I guess that answer nailed it
Strange that Microsoft does not have a more readily available way to share data, but I guess static method would do for now!
|
|
|
|
|
There's plenty of ways to share data, as I pointed out. How you share data depends on how both the setter and getting of that data intend to set and get that data. There's nothing generic about it.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
ok so I've done some thinking about this and here's what I've come up with. The XML file followed by Psuedo code followed by the code.
XML FIle:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<categories>
<category>Operating System</category>
<category>Productivity</category>
<category>Entertainment</category>
<category>Games</category>
<category>Misc.</category>
</categories>
<disk_numbers>
<disk>001</disk>
<disk>002</disk>
<disk>003</disk>
</disk_numbers>
</configuration>
Psuedo Code:
start in parent node "categories"
for each child node it has named "category"
check if innerText is equal to the selected item in the combo box
if it is
remove the child node
if it isn't
go to the next child node
during one pass through the child nodes this can never fail since the combo box item wouldn't be
listed if it wasn't in the file
Code:
private void mainToolbarRemoveCategoryButton_ItemClick(object sender,
DevExpress.XtraBars.ItemClickEventArgs e)
{
XmlNode parentNode = configDoc.SelectSingleNode("/configuration/categories");
if(MessageBox.Show("Are you sure?", "Katalog", MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation) == DialogResult.No)
{
return;
}
else
{
foreach(XmlNode n in parentNode)
{
if(n.InnerText.ToString() == programCategoryComboBoxEdit.SelectedItem.ToString())
{
try
{
parentNode = n.ParentNode;
parentNode.RemoveChild(n);
configDoc.Save("katalog.config");
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
So hopefully it's obvious what I'm trying to do, I guess the foreach loop is where the issue is, is this how I would traverse each child node?
thanks!
|
|
|
|
|
Although I don't know what the "issue" is, you're talking about, and this makes helping a bit hard, I think you're right with the foreach loop as cause.
MSDN clearly states that "the foreach statement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects."
As your code removes nodes from ChildNodes collection, that's probably the problem. So switch to a for loop and the problem should be gone:
XmlNode n;
for (int i = 0; i < parentNode.ChildNodes.Count; i++)
{
n = parentNode.ChildNodes.Item(i);
if(n.InnerText == programCategoryComboBoxEdit.SelectedItem.ToString())
{
parentNode = n.ParentNode;
parentNode.RemoveChild(n);
}
}
configDoc.Save("katalog.config");
www.troschuetz.de
|
|
|
|
|
Yes, enumerables should not be changed while enumerating them. The IEnumerable implementations in the .NET BCL - as should all IEnumerable implementations - keep a serial number that changes when the underlying enumerable changes. When MoveNext is called those serial numbers are compared and an exception is thrown if they differ.
Your sample code is a correct approach except for one problem: if you delete a node you must decrement the maximum value unless it would happen automatically (and in this case it would), and decrement the iterator (here, i ) so that in the next iteration of the loop the child element is re-read (since the nth element just because the (n-1)th element.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks man, got it all working now, appreciate the help
|
|
|
|
|
Could I have an example how to make what richTextBox1.SelectionIndent does but measuring in tabs instead of pixels ?
(I want to insert tabs in front of certain lines)
|
|
|
|
|
Tabs are characters. If you need to set a "tab" as Word denotes it, the RichTextBox.SelectIndent is the correct way. This changes the indentation of a paragraph but does not use a tab character, for changes in that paragraph would require a fairly complex algorithm to go and reposition tab characters.
What you should do is get the Font of the currently selected paragraph (using RichTextBox.SelectionFont ), the do something like this:
Graphics g = CreateGraphics();
SizeF size = g.MeasureString("\t", richTextBox1.SelectionFont);
int indentation = (int)size.Width;
richTextBox1.SelectionIndent = indentation;
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
|
Hi,
is it possible to highlight certain words in a textbox by giving them a different font or background color? I want to filter some words in this textbox. I did not find a way even with rtf boxes.
Thanx!
MG00c2x
|
|
|
|
|
Hi!
You can do this (at least the font thing) with the plain .NET RichTextBox class. Read the documentation for RichTextBox to see how to do it (SetSelectionFont ).
To set the background color for a part of your text you'll have to use interop to set the character format (look up 'CHARFORMAT2' on MSDN).
mav
|
|
|
|
|
Yes, it can be easily done in a rich text box. Please read the following example.
The following example displays a ColorDialog to the user to specify a color for the current text selection or text entered after the current insertion point in a RichTextBox control. This example assumes that the method defined in the example is added to a Form class that contains a RichTextBox control named richTextBox1.
[Visual Basic]
Public Sub ChangeMySelectionColor()
Dim colorDialog1 As New ColorDialog()
' Set the initial color of the dialog to the current text color.
colorDialog1.Color = richTextBox1.SelectionColor
' Determine if the user clicked OK in the dialog and that the color has
' changed.
If (colorDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK) _
And Not(colorDialog1.Color.Equals(richTextBox1.SelectionColor)) Then
' Change the selection color to the user specified color.
richTextBox1.SelectionColor = colorDialog1.Color
End If
End Sub
[C#]
public void ChangeMySelectionColor()
{
ColorDialog colorDialog1 = new ColorDialog();
// Set the initial color of the dialog to the current text color.
colorDialog1.Color = richTextBox1.SelectionColor;
// Determine if the user clicked OK in the dialog and that the color has changed.
if(colorDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
colorDialog1.Color != richTextBox1.SelectionColor)
{
// Change the selection color to the user specified color.
richTextBox1.SelectionColor = colorDialog1.Color;
}
}
Regards,
Sugandh
|
|
|
|
|
Hi there,
I've used the following string to create a multiline string.
String str = "line1 \n newline2 \n newline3";
but I didn't get the appropriate result. I got something like this:
line1 newline2 newline3
How can I create multi line string?
thank you in advance.
|
|
|
|
|
Try replacing '\n' with line feed '\x0a' and carriage return = '\x0d'
|
|
|
|
|
I think you cannot save the currage return functionality in a string.
Try Console.WriteLine("line1\nnewline2\nnewline3");
or
String str1 = "line1";
String str2 = "newline2";
String str3 = "newline3";
Console.WriteLine(str1 "\n" str2 "\n" str3 );
hope this helps
|
|
|
|
|
Use "\r\n" instead of just "\n"
|
|
|
|