|
Hi:
Trying to know more about C# and its libraries ...
Without using explicit iterations, how could I:
1) Determine if a character is in a list of characters? For example if I want to know if the content of variable v is in a list containg 'a','j','1','%'. I normally do: if (v[i] == 'a' || v[i] == 'j' ..... but it is too long if I use with many characters in the list. I would like something like (if a[i] in ('a','j','1','%')) for example.
2) For writing the character ',' 600 times I would like to do this:
write(600(',')), for example and not use for statement.
Seems to be disheveled but .... May there may be alternatives.
Best regards
|
|
|
|
|
It worked.
I only changed IndexOfAny by IndexOf
Thanks for opening my eyes and ... my mind.
Best regards.
|
|
|
|
|
Hi all,
I need some major clarification on the thread locking mechanism. This might be a bit long so please bear with me.
Supposing we have a class definition as follows:
Class X
{
private Y obj1;
private Z obj2;
public void Ftn1()
{
lock (this) // section 1
{
obj1.ModifyThis();
}
}
public void Ftn2()
{
lock (obj2) // section 2
{
obj2.ModifyMe();
}
}
public void Ftn3()
{
lock (this) // section 3
{
obj2.ModifyMe();
}
}
}
// main ftn.
X mainObj;
Thread A new ThreadStart(mainObj.Ftn1());
Thread B new ThreadStart(mainObj.Ftn2());
Thread C new ThreadStart(mainObj.Ftn3());
// start them all now
My question are:
Q1. Since Ftn1 has a 'lock(this)' code block, if thread 'A' started first,
will 'B' and 'C' have to wait till 'A' is done (even though their jobs are to do ftn2 and ftn3. I ask this because, 'X' has been explicitly locked in the call to 'Ftn1', and 'Ftn2' and 'Ftn3' belong to this 'X'?
Note: My current understanding is that the 'lock(this)' call is actually only locking that section of code i.e. only this method is locked, but the 'this' now has me confused and I need it cleared up before I proceed any further.
Q2. If you look at Ftn2 and Ftn3, they lock different things, but acces the same resource, so my question is if Ftn2 fires first, then will all go well i.e. Ftn3 will have to wait till the lock on obj2 is released, but if ftn3 fires first, there is a possibility that obj2 will get a corrupted result but deadlock will never occur?
If my assumptions are true then I can continue on with endless coding more satisfied and releived.
Any other input or advice will also be very welcome. Thanks for reading.
|
|
|
|
|
Answer to Q1:
Fcn1 and Fcn3 will be synchronized, because they both lock "this", only one of them can go on at a time. Fcn2 will execute regardless what happens in Fcn1 and Fcn3, because it is locking a different object (obj2).
Answer to Q2:
Fcn2 and Fcn3 can execute concurrently, since they are modifying the same object, the code will not be thread-safe.
In general, if two blocks of code are locking the same object, then only one of them can be executed, the other will wait its turn. If they are locking different objects, even if one of the objects being locked is a member of the other object, the two blocks of code can execute concurrently.
Hope this helps.
My articles and software tools
|
|
|
|
|
This definitely helps, thank so much. But then how can I ever do the following:
If say a class 'Service' offers three services:
Class Service
{
void Service1()
{
// modify x
}
void Service 2()
{
// modify y
}
void Service3()
{
// modify z
}
}
and I there are 'n' number of threads, each wanting to do only 1 of these services. I want the ability to be able to only do 'method' locks, not lock the whole object meaning that services should be able to run simultaneously, becuase I know that these services modify different resources. No 2 thread should be able to enter the same service. C# only provides for
lock(...)
{
}
there is no syntax like
lock // this block of code
{
}
or is there?
Thanks again.
|
|
|
|
|
link_79 wrote:
No 2 thread should be able to enter the same service
link_79 wrote:
I know that these services modify different resources
In each method, just lock the variables modified in that method, this way, each method is somehow locked separately and services will run simultaneously.
I lock my house, I lock my car and I pull that zipper on my pants up several times a day, just for the sake of security.
|
|
|
|
|
link_79 wrote:
Class Service
{
void Service1()
{
// modify x
}
void Service 2()
{
// modify y
}
void Service3()
{
// modify z
}
}
A simple solution is:
Class Service
{
void Service1()
{
lock(x)
{
}
}
void Service 2()
{
lock(y)
{
}
}
void Service3()
{
lock(z)
{
}
}
}
When I say "lock" a block of code, I meant
lock(TheObjectToBeLocked)
{
// block of code
}
My articles and software tools
|
|
|
|
|
Geez, that solution was staring me in the face, but my internal bulb never went off. My doubts with the 'lock(this)', threw me off course. Thanks for all the help guys.
|
|
|
|
|
link_79 wrote:
Since Ftn1 has a 'lock(this)' code block, if thread 'A' started first,
will 'B' and 'C' have to wait till 'A' is done
Yes they have, because all the instance have been Locked.
|
|
|
|
|
Hi all
I'm trying ing to create usercontrols dynamically and add them into a placeholder. During a postback i got the following error
" Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request. "
Is there any way I can solve this problem?
|
|
|
|
|
This question should be asked in the ASP.NET forum[^]. This forum is for questions specific for the C# language.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
i had a question i've been wondering about... when using winforms, you have to access controls on the same thread that owns that control, so from another thread you have to create a new delegate and call it via Invoke(), which marshals the call to the owning thread and works fine. my concern is the creation of the new delegate every time you call Invoke(). if I am calling Invoke very often, then the new delegate you have to create and pass to it would be rather inefficient, right? because when i do call Invoke, in my case i do know which function i want to be called at compile time, and it seems more efficient to create the delegate once, and pass that same object to Invoke everytime it's called. however, when trying to create a delegate like so:
public void delegate handler();
handler delegate_handler = new handler(myFunc);
i get some compile time error about not being able to reference non-static stuff.
any comments or suggestions?
|
|
|
|
|
You don't need to create the delegate each time. If you're invoking the same method over and over again, create the delegate once and keep a reference to it. It's merely a managed method pointer.
You can create a delegate that references both static and instance methods, but you have to include either the class name or the object reference with the method, just as if you were going to call the method without using a delegate (and the same rules for methods defined on the executing class are the same as well).
So, lets say you want to set the text for a TextBox from another thread and you expect to do it quite a bit. Do something like this:
private delegate void SetValueDelegate(object obj, object value,
object[] index);
private SetValueDelegate _setValueDelegate;
public void SafeSetText(TextBox tb, string value)
{
if (tb == null) throw new ArgumentNullException("tb");
if (tb.InvokeRequired)
{
if (_setValueDelegate== null)
{
PropertyInfo pi = tb.GetType().GetProperty("Text");
_setValueDelegate= new SetValueDelegate(pi.SetValue);
}
tb.Invoke(_setValueDelegate, new object[] {tb, value, null});
}
else tb.Text = value;
} This is just a sample, of course, but notice how I create a delegate that references an instance method using pi.SetValue . Even though the delegate isn't referencing a method on the control (that's much easier; with getting/setting properties you have to use reflection or the component model), the delegate is still invoked in the control's thread in which it was created.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'm hammering a richtextbox with huge amounts of text at a very fast pace
and using a wide variety of color-coding and multiple font styles. It works
reasonably well for the most part, but every so often the following two
things happen:
1) sometimes things don't get color-coded
2) exception is thrown
A coworker of mine tried the same thing, and reported the same type of
instability with the richtextbox... Is there something I can use that is
stable when using mass amounts of text with tons of varied colors and fonts?
Or is there a way to fix this instability in the richtextbox?
Thanks.
|
|
|
|
|
What do you need the RichTextbox for?
I know of a few other editors that have support for varied colors, but I don't know any that allow multiple fonts.
Aaron Eldreth
TheCollective4.com
My Articles
While much is too strange to be believed,
Nothing is too strange to have happened.
- T. Hardy
|
|
|
|
|
which tool do you suggest i use then? i want to be able to do a ton of color coding and changing of fonts and styles.
it seems of all the tools provided, richtextbox seems the most versatile. i don't think i can do the same things with a listview.
i am writing a test tool that outputs a ton of text for logging. it would be nice for things to be color coded and styled according to severity.
|
|
|
|
|
I'm really sorry, I don't know of any editors that can do what you want. So, you could either try to create your own edit control for your neads, or abandon the richtextbox and go for the textbox.
Aaron Eldreth
TheCollective4.com
My Articles
While much is too strange to be believed,
Nothing is too strange to have happened.
- T. Hardy
|
|
|
|
|
Hi,
I try to update Sql server DB with update from dataset but fails on the DataAdapter.Update with insert exception. here's my code :
<br />
<br />
try<br />
{<br />
<br />
sSQLSel = @"SELECT * From MidnightReadings";<br />
sSQLUpd = @"UPDATE MidnightReadings SET MR_Date = @MR_Date, Coal_Feeder_Tot = @Coal_Feeder_To" +<br />
"t, Coal_Silo_Level_Prct = @Coal_Silo_Level_Prct, Coal_Barn_Inv_Prct = @Coal_Barn" +<br />
"_Inv_Prct, Limestone_Feed_Total = @Limestone_Feed_Total, LS_Silo_Level_Prct = @L" +<br />
"S_Silo_Level_Prct, Ammonia_Totalizer = @Ammonia_Totalizer, Prop_to_Burn_Totalize" +<br />
"r = @Prop_to_Burn_Totalizer, TwentyFourHr_SO2_Reduct = @TwentyFourHr_SO2_Reduct," +<br />
" Limestone_Received = @Limestone_Received, Ammonia_Received = @Ammonia_Received," +<br />
" Prop_Received = @Prop_Received, Est_hours_Dry_Oper_Hours = @Est_hours_Dry_Oper_" +<br />
"Hours, Est_hours_Dry_Oper_Mins = @Est_hours_Dry_Oper_Mins, LAB_Sulfur_Content_Pr" +<br />
"ct = @LAB_Sulfur_Content_Prct, LAB_High_Heat_Val = @LAB_High_Heat_Val, CEMS_SO2_" +<br />
"Daily_Avg = @CEMS_SO2_Daily_Avg, SO2_Daily = @SO2_Daily, Raw_Water_Pump_Meter = " +<br />
"@Raw_Water_Pump_Meter, Reservoir_Level = @Reservoir_Level, Comments = @Comments," +<br />
" Date_Rec_Added = @Date_Rec_Added WHERE (MR_Date = @MR_Date)";<br />
<br />
<br />
SqlConnection myCon = new SqlConnection(sCon1);<br />
<br />
SqlDataAdapter da = new SqlDataAdapter(sSQLSel, myCon);<br />
<br />
da.UpdateCommand = new SqlCommand(sSQLUpd, myCon);<br />
<br />
<br />
buildMNUpdParams(da.UpdateCommand);<br />
da.Update(dsDiff,"MidnightReadings"); <- Fails here !<br />
dsDiff.AcceptChanges();<br />
myCon.Close();<br />
<br />
return true;<br />
<br />
public static void buildMNUpdParams(SqlCommand workCommand)<br />
{<br />
<br />
<br />
SqlParameter workParam = null;<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@MR_Date", SqlDbType.DateTime, 8));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "MR_Date";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Coal_Feeder_Tot", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Coal_Feeder_Tot";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Coal_Silo_Level_Prct", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Coal_Silo_Level_Prct";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Coal_Barn_Inv_Prct", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Coal_Barn_Inv_Prct";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Limestone_Feed_Total", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Limestone_Feed_Total";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@LS_Silo_Level_Prct", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "LS_Silo_Level_Prct";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Ammonia_Totalizer", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Ammonia_Totalizer";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Prop_to_Burn_Totalizer", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Prop_to_Burn_Totalizer";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@TwentyFourHr_SO2_Reduct", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "TwentyFourHr_SO2_Reduct";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Limestone_Received", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Limestone_Received";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Ammonia_Received", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Ammonia_Received";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Prop_Received", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Prop_Received";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Est_hours_Dry_Oper_Hours", SqlDbType.Int, 4));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Est_hours_Dry_Oper_Hours";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Est_hours_Dry_Oper_Mins", SqlDbType.Int, 4));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Est_hours_Dry_Oper_Mins";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@LAB_Sulfur_Content_Prct", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "LAB_Sulfur_Content_Prct";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@LAB_High_Heat_Val", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "LAB_High_Heat_Val";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@CEMS_SO2_Daily_Avg", SqlDbType.Int, 4));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "CEMS_SO2_Daily_Avg";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@SO2_Daily", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "SO2_Daily";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Raw_Water_Pump_Meter", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Raw_Water_Pump_Meter";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Reservoir_Level", SqlDbType.Decimal, 9));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Reservoir_Level";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Comments", SqlDbType.VarChar, 200));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Comments";<br />
workParam = workCommand.Parameters.Add(new SqlParameter("@Date_Rec_Added", SqlDbType.DateTime, 8));<br />
workParam.Direction = ParameterDirection.Input;<br />
workParam.SourceColumn = "Date_Rec_Added";<br />
workParam = workCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@MR_ID", System.Data.SqlDbType.BigInt, 8, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "MR_ID", System.Data.DataRowVersion.Original, null));<br />
}<br />
<br />
Any ideas ?
Thanks,
JJ
|
|
|
|
|
Could you post the exception? That's a lot of code to look through with out any sort of clue as to where to start looking.
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
My Blog
|
|
|
|
|
I am getting an InvalidOperationException with a message of "Insert". That's it, pretty useless message. Only hints that it didn't like my Statement for update command I guess. I am using a diffgram dataset to update database.
JJ
|
|
|
|
|
If your DiffGram includes inserts, updates, and deletes, all the related properties on a DataAdapter must be assigned. So, if a row was updated and all you supplied was the InsertCommand , then you would see such an operation because the DataAdapter doesn't know how to update the data store.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
HI Heath,
That's what I thought too. So in the method that I use to update db. I assigned the Insert command to DataAdapter along with the Update command to DataAdapter. Now it runs but when I execute the DataAdapter update method. I get a new row in database instead of actually updating same row. When I update the datarow with values how do I tell the diffram dataset to go to update mode as well?
Here I find the datarow I want to update in dataset:
<br />
nRow2 = dsDiff.Tables["MidnightReadings"].Select(sRecFind);<br />
It finds it in dataset with no problem
Then I update datarow:
<br />
nRow2[0]["Coal_Feeder_Tot"] = tbCoalFeederTot.Text;<br />
nRow2[0]["Coal_Silo_Level_Prct"] = tbCoalSiloPrct.Text;<br />
nRow2[0]["Coal_Barn_Inv_Prct"] = tbCoalBarnInvPrct.Text;<br />
nRow2[0]["Limestone_Feed_Total"] = tbLimeFeedTot.Text;<br />
I checked the dataset and changes are there but here is the status of row:
<br />
<MidnightReadings diffgr:id="MidnightReadings2" msdata:rowOrder="1" diffgr:hasChanges="inserted"><br />
<MR_Date>2004-06-10T00:00:00.0000000-04:00</MR_Date><br />
<Coal_Feeder_Tot>8789</Coal_Feeder_Tot><br />
<Coal_Silo_Level_Prct>95.5</Coal_Silo_Level_Prct><br />
<Coal_Barn_Inv_Prct>75.8</Coal_Barn_Inv_Prct><br />
<Limestone_Feed_Total>0</Limestone_Feed_Total><br />
<LS_Silo_Level_Prct>0</LS_Silo_Level_Prct><br />
...<br />
This dataset already exists in db but keeps inserting new records.
What am I missing?
Thanks,
JJ
|
|
|
|
|
Make sure the row information contains a primary key so that the UpdateCommand can effectively use a WHERE clause so that the right row is updated.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi Heath,
Ok really frustrated with trying to create a diffgram dataset.
I assume that I should first create a DataAdapter then build SqlCommand,InsertCommand, UpdateCommand for Adapter, Correct?
Next build parameters for each Commmand, Correct? After that I can then
Fill dataadapter, correct? Then I write my diffgram out to a file.
Does this sound like the correct approach to this?
After I do this I then take dataset and do inserts, updates etc. to
dataset. After done with this process I go back create a new dataadapter with whats mentioned above and call DataAdapter.Update.
What do you think? I did away with the webservice and have the create diffgram and database updates in a separate class.
Thanks,
JJ
|
|
|
|
|
To call Fill , you only need the SelectCommand set. When you call DataAdapter.Update , however, you may need all four set depending on what changes have been made. After calling Update , though, there will be no changes because the DataAdapter then calls AcceptChanges on your DataSet or DataTable (whichever you passed in).
So, you really only need to write out a DiffGram (if that's really necessary) after you make changes, otherwise those won't be any differences.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|