|
A very long post, a very long problem and a very long solution.
From what I understand you want to have shared objects (atomic objects) that can be modified using a transactional mechanism. And your main problem is that when a transaction is running what data you show to other requests.
If this is the case why don't you do as in a sql transactional server? When a transaction is started the atomic object is blocked until the transaction finishes succesfully or not. As for the data you provide to client requests, you don't give them acces to the main object, but to a clone of the object. And all changes must be made using an global object that supplies procedures following some rulles (meaning that in order to change the list of the object, you don't change the list, but call a procedure of that global object that does the job).
There are a couple of ways you could handle the transactional mechanism. One of them is to use a transaction object on which you use a mutex or something.
Hope this helps.
I have no smart signature yet...
|
|
|
|
|
Stanciu Vlad wrote: A very long post, a very long problem and a very long solution.
Indeed.
Stanciu Vlad wrote: From what I understand you want to have shared objects (atomic objects) that can be modified using a transactional mechanism. And your main problem is that when a transaction is running what data you show to other requests.
That's right.
Stanciu Vlad wrote: If this is the case why don't you do as in a sql transactional server? When a transaction is started the atomic object is blocked until the transaction finishes successfully or not. As for the data you provide to client requests, you don't give them access to the main object, but to a clone of the object.
Yeah, this is what I want to do. The problem is how. I have almost everything figured out except for the issues with the clones.
Stanciu Vlad wrote: And all changes must be made using an global object that supplies procedures following some rules (meaning that in order to change the list of the object, you don't change the list, but call a procedure of that global object that does the job).
This is what I had in mind. However, my main problem (problem #2, making sure they don't leave any references to the clone) still remains. Updating the right object isn't really problematic, I just didn't like the way I'm doing it now (replacing the fields one by one, as explained in problem #1). But when I give the programmer a clone instead of the global copy, what if he then goes and puts it in a dictionary or something? Then when the transaction commits there will be some references to the global object and some to the clone.
Stanciu Vlad wrote: There are a couple of ways you could handle the transactional mechanism. One of them is to use a transaction object on which you use a mutex or something.
I've been investigating this and I'm not having much luck, maybe you can help with this. The thing is, the whole point of my project is writing this transactional system (it's a software transactional memory[^] system). It's important that I have control over conflict resolution between transactions (deciding which one wins when they compete for the same lock) and what happens at commit, rollback, etc. From what I can see, Transaction[^] doesn't give me that control, since I cannot override TransactionManager[^]. Please correct me if I'm wrong (I hope I am).
Thanks for your help, I know this is pretty heavy stuff.
|
|
|
|
|
I think that tracking the clone is not the right way to do this; and .net's Transaction and TransactionManager classes I don't know if they wore built for customization. I looked a bit with Reflector in that assembly and all I can say is that messy stuff happens there.
The way I see a system like this is:
1) you should set up a workspace, the place where you keep your objects (original ones).
2) every clone provided to the user outside a transaction is "as it is". It's only purpose is to store values.
3) inside transactions, that's where all the crazy stuff takes place. A transaction should have a context (and by context I mean a part of or all the objects managed in the system workspace cloned and stuffed togheter outside the workspace). In the transaction context the user can do whatever he likes with the objects, because when he commits the transaction, the whole transaction context (meaning the changed objects) replaces the system workspace.
4) when a users requests to read or write a object in the context (the get or set method, or whatever implementation you have there) the object should be locked to the transaction that owns the context, and all the other transaction contexts should be notified about this lock (you do not want two users to change the same object in aproximatively the same time and both transactions to be comitted succesfully)
5) when a transaction is finished (successfully or not) all the objects locked to that transaction should be unlocked.
If you follow these steps maybe you can use the system like this:
using(MyCustomTransaction trans = new MyCustomTransaction())
{
trans.Context.TransactionalObject.x = 10;
(trans.Context.ManagedObjects["my object"] as aCustomTransactionalType).y = trans.Context.TransactionalObject.x * 100;
}
If you follow these steps there will be a lot of "lock(someContext)" and stuff like that. And the object locking mechanism in my opinion is the most messy part. A solution is to make a Mutex for each object in the system workspace, and center all the action in your TransactionManager and Transaction based on those mutex'es.
I don't know if this was the type of answer you were expecting )
I have no smart signature yet...
|
|
|
|
|
Hi Stanciu. Thanks for your answer.
What you describe is very similar to what I do. I actually have class called TransactionContext
But... I have problems with the following:
Stanciu Vlad wrote: In the transaction context the user can do whatever he likes with the objects, because when he commits the transaction, the whole transaction context (meaning the changed objects) replaces the system workspace.
Yes, but that requires registering the reads/writes somehow, and I don't know how to do that without tracking the objects. I do have write logs and read logs where I will register such accesses, but I don't know how to detect the accesses without somehow extending the code of the object's class to make the object notify them when they happen.
Actually, ideally what I'd like is to be able to write a monitoring agent that sees the bytecode that is running and registers every read/write, but I don't know how to do this in C#. I do know how to write the agent, but I don't know how to "plug it in" so that it can see the running bytecode. If you know how to do this it would pretty much solve all my problems, and I like it way better than what I'm doing right now -- which by the way doesn't work
Apart from that, my locking policy is slightly different, etc, but it would work if I can detect and register accesses correctly.
Thanks again for your answer
|
|
|
|
|
You problem seemed like a challenge for me , so, in the weekend, having some spare time in front of the computer, I've created a basic transactional system. It is basic because it can't use communicate with other processes, it only works inside the same application domain (manages multiple threads), but in my opinion it can be extended.
Do you want the source code? (maybe this will provide more answers for you).
I have no smart signature yet...
|
|
|
|
|
|
i have a system paramters table in my sql server to control everything about the system and I am currentlly saving all parameters as public variables in my C# windows form applicaton upon user login to the system..
I was just thinking if that's the best practice to do or I should save all in a local INI or XML file upon the user login the replace the file everytime the user login again?
what's your recommandation?
|
|
|
|
|
It all depends on your security requirement. Having an ini or xml file to store said data would render it available for tampering at will whilst variables make it quite difficult for your normal users.
If the post was helpful, please vote, eh!
Current activities:
Book: Devils by Fyodor Dostoyevsky
Project: Hospital Automation, final stage
Learning: Image analysis, LINQ
Now and forever, defiant to the end.
What is Multiple Sclerosis[ ^]?
|
|
|
|
|
what if i encrypt it in the local file or make it in a binary file for example?
|
|
|
|
|
Encrypting would still leave it open for tampering, whether malicious or not.
If the string "XLJKHSD7FR6W2345HLKSDFHO978W642O5KJH3RFO987Y" was the Base64 equivalent of some password, then if I change an alphanumeric character I have rendered the whole thing useless. Don't forget, INI and XML files are clear text. I would be against having clear text files that contain such crucial information.
A binary file would hamper any tampering effects, but that doesn't mean that the file could be deleted, again by mistake or on purpose.
If the post was helpful, please vote, eh!
Current activities:
Book: Devils by Fyodor Dostoyevsky
Project: Hospital Automation, final stage
Learning: Image analysis, LINQ
Now and forever, defiant to the end.
What is Multiple Sclerosis[ ^]?
|
|
|
|
|
Won't help against a hacker, he has the program and therefore either the key or the code that retrieves/calculates the key (and, therefore, the key). The only way to make it impossible for a hacker to get the key, would be to give the program no knowledge about the key or how to get it, but then you're stuck with an encrypted file which you can not decrypt.
There are many ways to make it "harder" for normal users to mess around too much, of course.
Making it a binary file would help, putting it through a DeflateStream would help too, xoring every byte with some funny number (say 0x34) would also help - but only against normal users.
They could, of course, randomly mess the file up..
|
|
|
|
|
I prefer to access the database each time a parameter value is required.
For one thing, it allows changing the configuration without restarting the application.
I use a class that offers properties that access the parameter database.
|
|
|
|
|
Hi there
I need print something with variable number of copies.
I used printdocument component.
private void Print_b_Click(object sender, EventArgs e)
{
printDocument1.PrinterSettings.Copies = 2;
printDocument1.Print();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.PageSettings.PrinterSettings.Copies = 2;
e.Graphics.DrawString("Test Print", new Font("Tahoma", 14, System.Drawing.FontStyle.Bold), Brushes.Black, 50, 50);
}
I used PrinterSettings.Copies = 2; in both block but does't work.
If you know why? tell me please.
Best Regards,
Reza Shojaee
|
|
|
|
|
hi all, i have one small question...
do we have ScaleTransform in winforms like that we are having WPF ?
i need to do some work regarding this? please help me
|
|
|
|
|
yes.
doesn't Google work where you are?
|
|
|
|
|
Hello guys,
I'm reading from a database using this called below:
private void GetAllMembers()
{
string query = @"SELECT * FROM [member_details] INNER JOIN club_details ON club_details.memberno = member_details.memberno WHERE [date_added] BETWEEN '" + date_from.SelectedValue.ToString() + "' AND '" + date_to.SelectedValue.ToString() + "'AND primsecconttype = '" + memb_type.SelectedValue.ToString() + "' AND [contracttype] = '" + class_type.SelectedValue.ToString() + "'";
try
{
conn.Close();
cmd = conn.CreateCommand();
cmd.CommandText = query;
conn.Open();
reader = cmd.ExecuteReader();
memb_names.Items.Clear();
while (reader.Read())
{
string firstnames = (string)reader["firstname"];
memb_names.Items.Add(firstnames);
}
if (!reader.Read())
{
error.Visible = true;
error.Text = "Sorry no mambers found in this range..";
}
}
catch (SqlException fff)
{
error.Visible = true;
error.Text = "Error occured: " + fff.Message;
}
}
The issue is that, when I read from a database and no record
is returned I would like to let the user know. it works when
I use an if() else statement but this will only return one
record if by chance the query returns something. A while loop
returns all the records, but I AM FAILING to find a way I can
let the user know if the query returns nothing after using a while loop.
Any help please on how I can let the user know if a while loop returns
nothing???
Thanks,
Mo
|
|
|
|
|
OK. First of all, look up parameterized queries, if you can't use stored procedures.
Second, I fail to realize what your problem is. Your while loop adds items to your collection, why not check the length of the collection after the while loop has run?
If it's 0 - obviously no records were returned.
And third: close your connection. Maybe add a finally statement to your try-catch ?
var question = (_2b || !(_2b));
|
|
|
|
|
Thanks man, you have made sound so simple.
I will try that
|
|
|
|
|
MorgSim wrote: Thanks man, you have made sound so simple.
I will try that
"It's all relative".
Seriously, good luck. I'm sure you'll get there.
var question = (_2b || !(_2b));
|
|
|
|
|
Hi.
i face a problem, record not update and no error show please check my coding and tell me where i do mistake
my coding is
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand();
conn.Open();
cmd.CommandText = "update contract set suppliername='" + dataGridView1.CurrentRow.Cells[1] + "',buyername='" + dataGridView1.CurrentRow.Cells[2] + "',contract_dt='" + dataGridView1.CurrentRow.Cells[3] + "',delivery='" + dataGridView1.CurrentRow.Cells[4] + "',pmode='" + dataGridView1.CurrentRow.Cells[5] + "',comm='" + dataGridView1.CurrentRow.Cells[6] + "',commper='" + dataGridView1.CurrentRow.Cells[7] + "' where contractid='" + dataGridView1.CurrentRow.Cells[0] + "'";
cmd.Connection = conn;
cmd.ExecuteNonQuery();
MessageBox.Show("Record Update..");
conn.Close();
}
|
|
|
|
|
If you are not sure what is going on, then enclose that code in a try...catch block and use
MessageBox.Show(ex.ToString()); to find out.
It may be that you have a try...catch block outside this method which is catching and discarding the error.
On a related note: change this to use parameterized queries, you are leaving yourself wide open to a SQL Injection attack. (Google for "Bobby Tables" to find out what that is)
P.S. When you give code fragments, always enclose them in <pre> </pre> blocks with the "code block" widget to preserve the formatting.
You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
The values you try to add to your ugly dynamic SQL are of type DataGridViewCell
So first of all, use dataGridView1.CurrentRow.Cells[x].Value to extract the values and as OriginalGriff already said, use parameterized queries.
It's easier, more readable, more efficient and NOT UGLY.
var question = (_2b || !(_2b));
|
|
|
|
|
hi i just want to display all empty fieldnames that are not filled up by the user
but my code has this errorer ' use of unassigned local variable 'messEmptyField' ; how can i fix this
<br />
private void btnSave_Click(object sender, EventArgs e)<br />
{<br />
string[] FieldName = { "Lastname", "Firstname", "Address", "Model", "Trouble Reported" };<br />
string messEmptyField;<br />
int i = 0;<br />
<br />
foreach (Control ctrl in groupBox1.Controls)<br />
{<br />
TextBox txt = ctrl as TextBox;<br />
<br />
if (txt.Text == string.Empty)<br />
{<br />
messEmptyField += FieldName[i];
}<br />
i++;<br />
}<br />
<br />
MessageBox.Show(messEmptyField + "please filled up all");<br />
dtDateLog.Focus();<br />
return;<br />
}<br />
<br />
<br />
<br />
<br />
|
|
|
|
|
This line:
string messEmptyField;
should probably be:
string messEmptyField = string.Empty;
|
|
|
|
|
hi
try this
string messEmptyField="";
|
|
|
|
|