|
I have just started worrking with Visual C# and I have just begun to read/write from an Access database. The application I built with guidance from the book I am using brings up all records in a database where you can scroll through, etc. The problem i am having is when i add a new record - the book doesn't show me how to check to see if the record already exists before adding it. The functionality I'm using in this application is ADO.net. Here is a code snippet from the book if that helps at all. I apologiz if i'm not being clear but i am really new to all this. Thanks for any help you can give.
DataRow drNewRow = m_dtContacts.NewRow( );
drNewRow[“ContactName”] = txtNewContactName.Text;
drNewRow[“State”] = txtNewState.Text;
m_dtContacts.Rows.Add(drNewRow);
m_daDataAdapter.Update(m_dtContacts);
m_RowPosition = m_dtContacts.Rows.Count – 1;
Contacts is the name of the Access DB.
|
|
|
|
|
|
TO check if a record exists first you do one of two things
1 - write a stored proc to do your insertions that does the check first
2 - run the SQL to check before you try to do the insert
Of course, if you have all the records in memory in a datatable, you can iterate over it, and I believe you can query it with SQL, too.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Hello
I'm using Graphviz to generate some diagrams of code relationships within our source code.
I have managed to get passable results with the jpg output, but the font rendering was pretty poor, therefore I changed to svg which produced better images and had the advantage of being scalable.
The next stage of my project is to embed an svg viewer into my C# app using .net2.
Does anyone have any tips or examples I could use?
Many thanks
Paresh
Paresh Solanki
"To the world, you may be just one person, but to one person, you may be the world"
|
|
|
|
|
Well, IE is how you view SVG documents usually, so embedd the web browser control, which is just IE, and will come with the SVG plugin you have installed.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Hi ,
I am creating a report using rdlc files. I want page break at the end of a group , but not at the end of last one.
In my example , I using a list . I have alreday put the condition for the page break , but its giving page break at the end of last group also , which i dont want.
Please let me know , how to proceed .
Thanks in advance ,
Vikram
|
|
|
|
|
I have troubles getting data out of a repeater. I know that it is not possible to retrieve data from repeater, so I used to read out every control in it.
But now I have encapsulated my Controls in the Repeater in a self-made UserControl:
<br />
<tr><br />
<td align=right><br />
<asp:Label id="cap" runat="server"/> :<br />
</td><br />
<td align="left" style="width:99%"><br />
<asp:PlaceHolder id="con" runat="server"/><br />
</td><br />
</tr><br />
code behind:
<br />
public partial class MergedControl : System.Web.UI.UserControl<br />
{<br />
public string Caption<br />
{<br />
get { return (cap.Text); }<br />
set { cap.Text = value; }<br />
}<br />
<br />
public Control Cont<br />
{<br />
get { return con.Controls[0]; }<br />
set { con.Controls.AddAt(0,value); }<br />
}<br />
}<br />
The reason why should be obvious: The Controltype often changes, that is why I hade to make it that way (Any ideas?)
Anyway, I can't retrieve the Value of the Control that is placed in the Placeholder. What am I doing wrong?
|
|
|
|
|
|
I have this code so far on checking collision. It doesn't quite work.
if (Velocity.Y > 0)<br />
{<br />
for (int n = 0; n < 25; ++n)<br />
{<br />
if (Position.Y + Sprite.Height > grassTopBlock[n].Position.Y<br />
&& Position.Y < grassTopBlock[n].Position.Y + grassTopBlock[n].Sprite.Height)<br />
{<br />
if (Position.X + Sprite.Width > grassTopBlock[n].Position.X<br />
&& Position.X < grassTopBlock[n].Position.X + grassTopBlock[n].Sprite.Width)<br />
{<br />
Position.Y = grassTopBlock[n].Position.Y - Sprite.Height;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
if (Velocity.X < 0)<br />
{<br />
for (int n = 0; n < 25; ++n)<br />
{<br />
if (Position.Y + Sprite.Height > grassTopBlock[n].Position.Y<br />
&& Position.Y < grassTopBlock[n].Position.Y + grassTopBlock[n].Sprite.Height)<br />
{<br />
if (Position.X < grassTopBlock[n].Position.X + grassTopBlock[n].Sprite.Width<br />
&& Position.X + Sprite.Width > grassTopBlock[n].Position.X + grassTopBlock[n].Sprite.Width)<br />
{<br />
Position.X = grassTopBlock[n].Position.X + grassTopBlock[n].Sprite.Width;<br />
}<br />
}<br />
}<br />
}
What the problem is, I can never tell if the second statement acts, because every time I try, the sprite moves to the top of the grassTopBlock. Can anyone post (or help?) with some collision algorithm for 2D sprites? thanks
- I love D-flat!
- Need. More. Code.
|
|
|
|
|
So, comment out the code that changes the y position and see if the x position code works alone.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
OK: never mind; I figured it out, fianlly. Thanks for helping, though.
The problem was that the Y value kept checking after a certain limit was supposed to be. I added 1 line and it was fixed.
- I love D-flat!
- Need. More. Code.
modified on Monday, March 17, 2008 7:07 PM
|
|
|
|
|
Hi all,
I've been a regular visitor lately but this is my first message. I (am trying to) program just for fun, not for profit, so please do not be harsh if I'm missing some basic concepts.
Starting from the sample code HiLow posted here by Michael Kitchen (http://www.codeproject.com/KB/game/hilow.aspx), I am trying to extend the example to a trick-based game such as spades or bridge.
The code has a Deck class but I need to create a Hands class aswell. For storing the cards that have been dealt, i created a class:
public class Hands<br />
{<br />
public int[,] PlayerHands = new int[4, 13];<br />
public Hands()<br />
{<br />
}<br />
}
The field PlayerHands [4,13] (i hope the dimensions are right) will store the four hands dealt from the deck.
Now, for dealing the cards I made a nice for loop, and it's working.
The problem is that the loop can work as far as I see in two ways:
A. like a void "procedure" - meaning I pass a Hands object to the "procedure" and it fills the correct field (array) with values, and returns nothing.
In this case I deal the cards this way:
TheDeck.DealHands (TheHands);
B. like a function - meaning I assign it's result to the Hands object (if it retunrs a hands object) or more likely to the playerhands field (array) of the hands object - in this case the return is an array of integers.
TheHands.PlayerHands = TheDeck.DealHands();
C. there was a third way, that was quite stupid, dealing the Hands in the constructor of the Hands class (with TheDeck passed as argument) - that was stupid because each new game meant the creation of a new instance of the Hands instead of re-using the same object variable.
Please help me decide which is better. Please note, both versions really work. I've tried to clean the code below of unnecesarry statements. If somethinf looks wrong I might heve deleted too much...
A. code in the first case:
public partial class Form1 : Form<br />
{<br />
private Deck TheDeck;<br />
private Hands TheHands;<br />
public Form1()<br />
{<br />
TheDeck = new Deck();
TheHands = new Hands();
}<br />
private void buttonPlay_Click(object sender, EventArgs e)<br />
{<br />
TheDeck.Shuffle();<br />
TheDeck.DealHands(TheHands);<br />
Invalidate();<br />
}<br />
}<br />
<br />
<br />
public class Deck<br />
{<br />
private int[] CardArray = new int[52];<br />
public Deck()<br />
{<br />
for( int i = 0; i < 52; i++ )<br />
{<br />
CardArray[i] = i;<br />
}<br />
}<br />
<br />
public void DealHands(Hands passedHands)<br />
{<br />
for (int j = 0; j < 13; j++)<br />
{<br />
for (int i = 0; i < 4; i++)<br />
{<br />
passedHands.PlayerHands [i,j]=CardArray[4 * j + i];<br />
}<br />
}<br />
}<br />
}<br />
}
B code in the second case:
public partial class Form1 : Form<br />
{<br />
private Deck TheDeck;<br />
private Hands TheHands;<br />
public Form1()<br />
{<br />
TheDeck = new Deck();
TheHands = new Hands();
}<br />
private void buttonPlay_Click(object sender, EventArgs e)<br />
{<br />
TheDeck.Shuffle();<br />
TheHands.PlayerHands = TheDeck.DealHands();<br />
Invalidate();<br />
}<br />
}<br />
<br />
<br />
public class Deck<br />
{<br />
private int[] CardArray = new int[52];<br />
public int[,] PlayerHands = new int[4, 13]; <br />
public Deck()<br />
{<br />
for( int i = 0; i &lt; 52; i++ )<br />
{<br />
CardArray[i] = i;<br />
}<br />
}<br />
<br />
public int [,] DealHands()<br />
{<br />
for (int j = 0; j &lt; 13; j++)<br />
{<br />
for (int i = 0; i &lt; 4; i++)<br />
{<br />
PlayerHands [i,j]=CardArray[4 * j + i];<br />
}<br />
}<br />
return PlayerHands;<br />
}<br />
}<br />
}
for me, both ways look to have same result but which one is better or more efficient please?
Thanks in advance.
Paul
|
|
|
|
|
Hi Paul,
Welcome to the forums! I'm just trying to get my head around what you're trying to do here. Firstly, hands - are these players? Are we assuming four players here? Also, what version of .NET are you using?
Regards,
Rob Philpott.
|
|
|
|
|
Hi pauli, Welcome to code project
To directly answer your question as briefly as possible, I prefer method B. It is a nice clean function call that performs an action and returns the result. Where possible I like to avoid passing objects and modifying them in a function as in a big system you quickly lose track of which objects are being modified where. As far as efficiency is concerned, the difference will be so tiny it's not worth worrying about. Choose readability & maintainability over efficiency in 99.9% of cases.
I do have some other comments though, as you seem to be asking about class design:
You have chosen to store the hands in a multi dimensional integer array.
pauli wrote: public int[,] PlayerHands = new int[4, 13];
To me, it seems that your combining several bits of information here that should really be separate.
Firstly, rather than an int, why not create a Card class that stores a value and a suit. (The suit member could be an enum). I personally don't like using basic data types (like int) to represent something more complex. In this case, you're using an int from 1-52 to represent a card. Well, when you come back to a bit of code in 6 months, you'll spend ages searching around to figure out what card number 36 was.
public enum CardSuit
{
clubs = 0,
hearts = 1,
spades = 2,
diamonds = 3
}
public class Card
{
private int _value;
private CardSuit _suit;
public int Value
{
get
{
return _value;
}
set
{
_value = value;
}
}
public CardSuit Suit
{
get
{
return _suit;
}
set
{
_suit = value;
}
}
}
Secondly, rather than using a multi dimensional array, (which presents problems if you were to change the number of hands required, or the number of cards in a hand). Why not try defining a class called PlayerHand which would store all the cards for 1 players hand. Inside the PlayerHand class, you could use a Collection<card> member to store the cards in the hand. Collections are easier than arrays to work with, as they can dynamically resize, and include nice add/remove methods. And they are still strongly typed like arrays thanks to generics. Browse around the System.Collections.Generic namespace to see the various available collections. There are different types like lists, dictionaries, etc for different uses.
public class PlayerHand
{
private Collection<Card> _cards;
public PlayerHand()
{
_cards = new Collection<Card>();
}
public Collection<Card> Cards
{
get
{
return _cards;
}
}
}
Finally, now you've got a class for each player hand, you can scrap the Hands class, and just use a collection. (Collection<PlayerHands>);
Now, you could modify your deal method to take in the number of players, and return a collection of the required number of hands:
Collection<PlayerHands> theHands;
theHands = TheDeck.Deal(4);
There's no "correct" way to do anything though, I'm sure other people here will give other opinions, this is just mine.
But back to your original question. I prefer style B.
(It's so nice to have someone ask a well thought out question! Good luck with your programming, feel free to ask more)
Simon
|
|
|
|
|
Rob, Simon,
Thank you for your replies.
To answer Rob's questions: I'm using VS Express 2005 with .NET 2.0.5.
Hands are not players, but are the cards dealt to players. Maybe I should make Player class and I don't even need a Hands class?
Anyway, there are 4 players and each one it's dealt a set of 13 cards.
I wanted the Hands class to have fields required for the AI (evaluating hands) - such as "ShortestSuit" , "LowestCardofShortestSuit"... Now I'm not even 100%sure I need this class. I could write the above methods as members of a Game class and store the hands in simple arrays (arrays of card objects). This way I could pass the array as argument for the hand evaluation functions.
Simon, thank you very much for your suggestions and examples. I do have a Card class in my project, which is a cards.dll wraper from Mike Kitchen's hilow source code posted here on codeproject:
<br />
<br />
using System;using System.Drawing;using System.Runtime.InteropServices;<br />
namespace miscelements.Windows.Cards<br />
{<br />
public enum CardSuit : int<br />
{<br />
Clubs = 0,<br />
Diamond = 1,<br />
Hearts = 2,<br />
Spades = 3<br />
}<br />
public enum CardRank : int<br />
{<br />
Ace = 0,<br />
Two = 1,<br />
Three = 2,<br />
Four = 3,<br />
Five = 4,<br />
Six = 5,<br />
Seven = 6,<br />
Eight = 7,<br />
Nine = 8,<br />
Ten = 9,<br />
Jack = 10,<br />
Queen = 11,<br />
King = 12<br />
}<br />
public enum CardBack : int<br />
{<br />
Crosshatch = 53,<br />
Sky = 54,<br />
Mineral = 55,<br />
Fish = 56,<br />
Frog = 57,<br />
Moonflower = 58,<br />
Island = 59,<br />
Squares = 60,<br />
Magenta = 61,<br />
Sanddunes = 62,<br />
Space = 63,<br />
Lines = 64,<br />
Toycars = 65,<br />
Unused = 66,<br />
The_X = 67,<br />
The_O = 68<br />
}<br />
public enum CardMode : int<br />
{<br />
RankCollated = 0,
SuitCollated = 1,
Highlight = 2, <br />
Ghost = 3, <br />
Remove = 4, <br />
InvisibleGhost = 5, <br />
DeckX = 6, <br />
DeckO = 7 <br />
}<br />
public class Card : IDisposable<br />
{<br />
internal const int DefaultWidth = 71;<br />
internal const int DefaultHeight = 97;<br />
internal const int BorderMask = 0x00FFFFFF;<br />
private Graphics graphicsSurface;<br />
private IntPtr graphicsDC;<br />
private bool lastReturnValue;<br />
private bool disposed;<br />
private static int mode;<br />
public int Mode<br />
{<br />
get { return mode; }<br />
set { mode = value; }<br />
}<br />
public Card()<br />
{<br />
int width = DefaultWidth;<br />
int height = DefaultHeight;<br />
mode = (int)CardMode.RankCollated;<br />
NativeMethods.cdtInit(ref width, ref height);<br />
}<br />
Mike's/Public Joe's code has some resemblances with your suggestions.
In your example, I see that each card will be an object, with value and suit as properties, accessed with property set / get. In Mike's code it seems to me that the value and suit are fields instead of properties.
I think using integers was needed for easier use of the dll. I do not mind.
The cards in the cards.dll are numbered from 1 to 52, with 1 to 13 being clubs, 14 to 26 being diamonds and so on... It's not hard to do the correct math to "extract" the real suit and value from these numbers.
Now I must confess I don't see yet how exaclty will I work with the cards in hands. Mike's hilow game does not deal the cards, but takes one card from the deck and shows it on the table. I am still learning from his source code. I just noticed this member of the card class and it's doing the math i was writing above (converts from suit and value to 1-52 numbers) :
public static int ToCardIndex( CardSuit suit, CardRank rank )<br />
{<br />
int cardNo = -1;<br />
<br />
switch( mode )<br />
{<br />
case 0: <br />
cardNo = ((int)rank)*4+((int)suit);<br />
break;<br />
<br />
case 1: <br />
cardNo = 1+((int)rank)+13*((int)suit);<br />
break;<br />
<br />
default:<br />
cardNo = 0;<br />
break;<br />
}<br />
return cardNo;<br />
}
The cards are objects while my Hands class works with an array of integers. I realize this might not make sense (althogh I think it could really work this way - I would do anythind in order to avoid an object ). At first I was wondering if I should work with an array of cards objects, but now I see you suggest working with a collection. I am yet to learn about this concept.
I'm not familiarized with many of the concepts used in your samples: enums, set / get, and collections, but that's why I'm doing this project - to learn.
Simon, I am gonna try all your suggestions. They look really promising and thanks again for spending some of your time to help me.
Edit: I am stuck.
I made a total mess out of it. What type is theHands? I assume Collection<playerhand> is a type?
Collection<playerhand> theHands; // why not = new Collection<playerhand>(); ?
// System.Type type = theHands.GetType();
// MessageBox.Show(Convert.ToString(type));
theHands = TheDeck.DealHands(4);
How do I refer to each hand? How do I assign a value to theHands?
I am trying to rewrite the DealHands method of the Deck class, but I can't make it work in the new way:
///.......
public class Deck
{
private int[] CardArray = new int[52];
private Collection<playerhand> aHand = new Collection<playerhand>();
/// ......
public Collection<playerhand> DealHands (int handsnumber)
{
for (int j = 0; j < 13; j++)
{
for (int i = 0; i < handsnumber; i++)
{
//passedHands.PlayerHands [i,j]=CardArray[4 * j + i];
aHand [i].Cards(j).set =CardArray[4 * j + i];
}
}
return aHand;
}
the above does not work - the error is Cards is a property and i am trying to use it as a method. I someone could drag me out of this messs, I would higly appreciate.
<joke>
otherwise, I'm back to VB6, forever !
modified on Tuesday, March 18, 2008 10:26 AM
|
|
|
|
|
pauli wrote: What type is theHands? I assume Collection is a type?
Collection theHands; // why not = new Collection(); ?
Collection is a generic type. This means that when you create a collection object you have to also provide a type parameter. The collection will then contain objects of the type you specified when you created it. So for a collection of ints you would define it like this:
Collection<int> myintcollection = new Collection<int>();
Don't forget to include a using statement at the top of the file to link to the namespace
using System.Collections.ObjectModel;
Google around for a tutorial on generics to help you understand this. There's loads out there.
pauli wrote: How do I refer to each hand?
Just like you would with an array.
theHands[1];
Or using a foreach loop.
<br />
foreach(PlayerHand hand in theHands)<br />
{<br />
{<br />
pauli wrote: How do I assign a value to theHands?
Once you've created the new collection like this
Collection<PlayerHand> theHands = new Collection<PlayerHand>()
you can call the Add(...) method to add new hands to the collection.
PlayerHand hand1 = new PlayerHand();<br />
theHands.Add(hand1);<br />
pauli wrote:
aHand[i].Cards(j).set =CardArray[4 * j + i];
the above does not work - the error is Cards is a property and i am trying to use it as a method
You're doing exactly what it says. Cards is a property of the hand object. By using round brackets your trying to call a method called Cards (which doesn't exist).
The Cards property is giving you access to a collection object containing all the cards in the hand, which you then want to access with a indexer (square brackets) to get the specific card you want to look at.
If you want to add a card to the collection use the .Add method.
aHand[i].Cards.Add(put the card you want to add here);
pauli wrote: otherwise, I'm back to VB6, forever !
Noooooooooo........
Simon
|
|
|
|
|
Hi,
There appears to be duplicates in my generic collection.
How do I delete the extra ones from inside the generic collection please?
Is there a distinct or group by in generic collection?
Thanks
|
|
|
|
|
Hi,
some facts:
most collections allow duplicate entries; Hashtable/Dictonaries typically do not.
the easiest way to avoid duplicates is to check for them when adding.
the easiest way to remove duplicates is to sort, then scan once for "same as previous".
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
Hi all,
I am writing a program that needs to take a login name and password, and then try to authenticate against an AD server. Sounds simple enough so far...
The name and password may be entered by a user (real human being), however it also may be generated by another application (actually, a hardware device that my application is communicating with) that I have no real control over. This other application always generates the "account name" for Active Directory users (so, if the user is First Name = "Ben", Last Name = "de Waal", Display Name = "Ben de Waal", but login name = "bdw123", then the value that is passed is "bdw123").
Using DirectoryEntry("LDAP://" + adServer, userName, userPass, authType) , it seems the userName should be "Ben de Waal" (from the above example) to be accepted - if I try "bdw123", it fails to authenticate. I was considering simply iterating through the user list and then getting the "Ben de Waal" value from the "bdw123" user, however it was pointed out to me (quite rightly) that you could have two users named "Ben de Waal", but with different account names. This would mean that the login attempt may then try the incorrect one, which would be very bad.
Can anyone point me in the right direction for checking the "account name"/password against AD rather than the "user name"/password?
|
|
|
|
|
Hi
I have a resource leak in the very simple project.
Project contains Form with one TextBox control in multiline mode.
After start this app I open Task Manager and see "Handles" count incremental on every 1 second.
The source code is following:
<code>
public partial class Form1 : Form
{
System.Threading.Timer tm;
public Form1()
{
InitializeComponent();
// start timer 1 second interval ...
tm = new System.Threading.Timer(OnTimer, null, 0, 1000);
}
void OnTimer(Object state)
{
// add text in thread safe mode ...
AddTerminalText(" Resource Leak!!! ");
}
delegate void AddTextCallback(string text);
AddTextCallback d;
object[] arg = new object[1];
private void AddTerminalText(string text)
{
if (textBox1.InvokeRequired)
{
if (d == null)
{
d = new AddTextCallback(AddTerminalText);
}
arg[0] = text;
textBox1.Invoke(d, arg);
}
else
{
textBox1.AppendText(text); // add text into control ...
}
}
}
</code>
I don't understand what's wrong
Please help anybody !!!
Roman
|
|
|
|
|
Hi,
I don't see anything wrong but have two comments:
1.
you could try the same with an empty OnTimer() and look for a difference in TaskManager.
2.
if that is the only thing the timer is supposed to do, you'd better use a Forms.Timer
which ticks on the GUI thread, hence no Invoke stuff required at all...
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
Hi
Yes of course.
The empty OnTimer handler removes resource leak.
The using Timer from Forms namespace removes leak too.
You are absolutely right.
But problem is that I need to add string into text control from other (not main window) thread
This simple project is created specially for demonstrate a standard method for
add a text string into TextBox control from other thread!
This demo is based on standard sample from MSDN and it has leak!!!
I know that the permanent resource leak is in following part of source code:
delegate void AddTextCallback(string text);
AddTextCallback d;
object[] arg = new object[1];
private void AddTerminalText(string text)
{
if (textBox1.InvokeRequired)
{
if (d == null)
{
d = new AddTextCallback(AddTerminalText);
}
arg[0] = text;
textBox1.Invoke(d, arg);
}
else
{
textBox1.AppendText(text); // add text into control ...
}
}
How I can add text correctly into text box from other thread ?
Roman
|
|
|
|
|
Hi Roman,
your code seems to be correct.
you are not dealing with handles yourself, the only thing you do is create some
objects; they will live their life, and end up being garbage collected. Nothing to
worry about.
you could try running it (with a faster timer, or a for loop somewhere) upto
millions of text lines; you will notice though that it slows down because a textbox
needs to concatenate text to do AppendText (a listbox would not really slow down
since it does not concatenate its items).
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
Hi Luc
I will try to test more ... Maybe GC wil wake up and will do its job ....
The problem that I see leak after remove AppenText() method at all:
private void AddTerminalText(string text)
{
if (textBox1.InvokeRequired)
{
// it seems like leak somewhere here ..........
if (d == null)
{
d = new AddTextCallback(AddTerminalText);
}
arg[0] = text;
textBox1.Invoke(d, arg);
}
else
{
//Don not change Text of control !!!!!! Line is commented out !!!!! Do nothing!!!!
//textBox1.AppendText(text); // add text into control ...
}
}
Anyway all this does not look good ...
Roman
|
|
|
|
|
Hi Roman,
as I told you before, AppendText appends new text to existing text, so it has to
allocate a new string and copy both parts in there, generating at least one object;
and a growing one, the more appends you do. So the GC is bound to kick in sooner
or later. If you find it hard to believe I suggest you try with a ListBox instead.
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|