|
|
I was looking at this article[^] on Threads vs. Tasks.
The end of the first paragraph says
Thread allows the highest degree of control; you can Abort() or Suspend() or Resume() a thread (though this is a very bad idea)
It is a bad idea and if so, why?
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
The problem with suspending a thread is that you have no real idea of what it's doing at the point you suspend it. Imagine you have a process where you read a load of data into memory and then use this to do a bulk insert into a database on a thread and you've taken a lock on a table. Your code issues a suspend statement just after you've started writing to the database - you've now locked the table indefinitely. There are other cases where this technique is equally bad - you've suspended inside a locked mutex for instance.
The case against Abort is just as bad. The big problem with it is that it kills the thread at that point (that's the theory anyway - while it's not trivial, it is possible to produce code that prevents a thread being aborted - malware writers are fond of this). You have no idea what's going on at that point, so you have no idea whether the exit has left resources in a clean state or not.
|
|
|
|
|
Good answer. Thanks
If it's not broken, fix it until it is
|
|
|
|
|
Ok this is a CONCEPT problem (the code is not professional, just read it for the concept, though it does compile and run).
Right, I have asked many people on IRC and no one is giving me a straight answer lol so maybe some professionals can help me.
I am trying to use a Datasource property for my combobox. This is so I can just pass an entire KeyValue pair with indexes and values to be shown in the listbox.
Creating the keyvaluepair as a WHOLE and passing that to datasource property works perfectly.
Creating a keyvaluepair PROCEDURALLY (in a loop or w/e) ends in the datasource property ToString()ing it, list box items show BOTH value AND display members in square brackets as an entire option.
NOTE: Getting the lsitbox.value results in ONLY the valuemember being returned even though the listbox shows both the valuemembers AND the displaymember? it knows they are different?
Now, I dont want any alternatives or comments about the quality of the code, all I want to know is WHY is it doing this, it seems compeltely illogical that the same TYPE and Values and can different Effects within the datasource property? Its like it knows it was built procedurally?
Anyway here is some code for reference:
namespace skbtInstaller
{
public partial class frmMainWindow : Form
{
public frmMainWindow()
{
InitializeComponent();
this.cBoxArmaPath.ValueMember = "Key";
this.cBoxArmaPath.DisplayMember = "Value";
}
public void addServerPathItem(String Key, String Value)
{
this.cBoxArmaPath.Items.Add(new KeyValuePair<String, String>(Key,Value));
}
public void setServerPathDatasource(List<KeyValuePair<String, String>> source)
{
this.cBoxArmaPath.DataSource = new BindingSource(source, null);
}
}
public class skbtServerControl
{
private frmMainWindow frmMainWindowHandle;
public void refreshformWindow()
{
this.frmMainWindowHandle.clearPathBox();
foreach (KeyValuePair<String, skbtServerConfig> pair in CoreConfig.getServerConfigList())
{
this.frmMainWindowHandle.addServerPathItem(pair.Key, pair.Value.getTextualName());
}
}
public void refreshformWindowWithSTATICDatasource()
{
this.frmMainWindowHandle.clearPathBox();
var pathDataSource = new List<KeyValuePair<String, String>>()
{
new KeyValuePair<String, String>("testKey1", "somevalue1"),
new KeyValuePair<String, String>("testKey2", "somevalue2"),
new KeyValuePair<String, String>("testKey3", "somevalue3")
};
this.frmMainWindowHandle.setServerPathDatasource(pathDataSource);
}
public void refreshformWindowWithDatasource()
{
this.frmMainWindowHandle.clearPathBox();
var pathDataSource = new List<KeyValuePair<String, String>>();
foreach (KeyValuePair<String, skbtServerConfig> pair in CoreConfig.getServerConfigList())
{
pathDataSource.Add(new KeyValuePair<String, String>(pair.Key, pair.Value.getTextualName()));
}
this.frmMainWindowHandle.setServerPathDatasource(pathDataSource);
}
}
}
Chemical Bliss
aka Uniflare
|
|
|
|
|
uniflare wrote: comments about the quality of the code
No worries, mate. We've seen worse!
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
When you put a breakpoint on the setServerPathDataSource for the problem code, what do you see in pathDataSource? How does it compare to the one that works? Do those objects actually appear identical internally?
|
|
|
|
|
Ok did some debugging, it seems that when i set a new datasource, the combobox.DisplayMember defaults to "". Although the combobox.ValueMember stays as "Key".
the fix Im using is to re-set DisplayMember to "Value" on each datasource update.
Is this a bug? Is it supposed to reset these properties when the datasource is set? or is it my implementation that is buggy?
All other factors are identical. The actual problem was only the very FIRST datasource set worked as intended, every subsequent datasource was displayed improperly with displaymembers and valuemember being shown in the listbox.
Revised Code Example: (Working with fix) (Compiles and runs with the components on designer..)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace etstapp1
{
public partial class Form1 : Form
{
private skbtServerControl sc;
public Form1()
{
InitializeComponent();
this.sc = new skbtServerControl(this);
this.cBoxArmaPath.ValueMember = "Key";
this.cBoxArmaPath.DisplayMember = "Value";
}
public void addServerPathItem(String Key, String Value)
{
this.cBoxArmaPath.Items.Add(new KeyValuePair<String, String>(Key, Value));
}
public void setServerPathDatasource(List<KeyValuePair<String, String>> source)
{
this.cBoxArmaPath.DisplayMember = "Value";
this.cBoxArmaPath.ValueMember = "Key";
this.cBoxArmaPath.DataSource = new BindingSource(source, null);
}
public void clearPathBox()
{
if(this.cBoxArmaPath.DataSource == null){
this.cBoxArmaPath.Items.Clear();
}
else
{
this.cBoxArmaPath.DataSource = null;
}
}
private void btnStatic_Click(object sender, EventArgs e)
{
this.sc.refreshformWindowWithSTATICDatasource();
}
private void btnNormal_Click(object sender, EventArgs e)
{
this.sc.refreshFormWindow();
}
private void btnDynamic_Click(object sender, EventArgs e)
{
this.sc.refreshformWindowWithDatasource();
}
}
public class skbtServerControl
{
private CoreConfig CoreConfig;
private Form1 frmMainWindowHandle;
public skbtServerControl(Form1 f){
this.frmMainWindowHandle = f;
this.CoreConfig = new CoreConfig();
}
public void refreshFormWindow()
{
this.frmMainWindowHandle.clearPathBox();
foreach (KeyValuePair<String, skbtServerConfig> pair in CoreConfig.getServerConfigList())
{
this.frmMainWindowHandle.addServerPathItem(pair.Key, pair.Value.getTextualName());
}
}
public void refreshformWindowWithSTATICDatasource()
{
this.frmMainWindowHandle.clearPathBox();
var pathDataSource = new List<KeyValuePair<String, String>>()
{
new KeyValuePair<String, String>("testKey1", "somevalue1"),
new KeyValuePair<String, String>("testKey2", "somevalue2"),
new KeyValuePair<String, String>("testKey3", "somevalue3")
};
this.frmMainWindowHandle.setServerPathDatasource(pathDataSource);
}
public void refreshformWindowWithDatasource()
{
this.frmMainWindowHandle.clearPathBox();
var pathDataSource = new List<KeyValuePair<String, String>>();
foreach (KeyValuePair<String, skbtServerConfig> pair in this.CoreConfig.getServerConfigList())
{
pathDataSource.Add(new KeyValuePair<String, String>(pair.Key, pair.Value.getTextualName()));
}
this.frmMainWindowHandle.setServerPathDatasource(pathDataSource);
}
}
public class CoreConfig
{
public Dictionary<String, skbtServerConfig> getServerConfigList(){
return new Dictionary<string, skbtServerConfig>()
{
{"somekey1", new skbtServerConfig("somename1")},
{"somekey2", new skbtServerConfig("somename2")}
};
}
}
public class skbtServerConfig
{
private String name;
public skbtServerConfig(String name)
{
this.name = name;
}
public String getTextualName()
{
return this.name;
}
}
}
Thanks guys, its not pretty and probably not the way to use datasources but at least i know what the problem was and the solution.
Though, If anyone can tell me why its resetting the members?
modified 17-Feb-15 16:32pm.
|
|
|
|
|
This would seem to indicate that the new BindingSource was resetting the values. While it may not be a bug, it's certainly not a very clever API design (by the designers of WinForms, not you I will hasten to add).
Okay, I've been having more of a think about this and I suspect that the reason that you need to do this is because when you change your BindingSource, the ComboBox has no concept of what it's bound to. You could be binding to something that doesn't use Key and Value here, so it forces you to update these values here.
modified 17-Feb-15 16:58pm.
|
|
|
|
|
Thanks for the detailed response, your explanation does seem logical.
Thanks again guys!
|
|
|
|
|
Great idea..Thanks for sharing your knowledge
|
|
|
|
|
Short Story: I'm a Newbie in application security. I need to implement a login via email.
Long Story: I have built a basic web chat application using SignalR, now i'm working in saving conversation in SQLServer Db. But my next challenge is to create a chat invitation email that will be send to all users from my db. The email should contain a link that when users will click they will be redirected to the chat web-page and automatically signed in.
My question is: Can it be done? And if it can, how can it be done
Thank you for your help!
modified 1-Jan-22 21:01pm.
|
|
|
|
|
A very insecure method to be actually implemented in an applicaton (or in any application).
But, yes, if you want to login the users automatically. Then you can create a URL that redirects the user to such a page where the UserName and the Password would be automatically set to login the user.
Tip: Instead of using a username/password there, you can use a token generated by the user each time he sends the email to others.
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
I have a DataGridView with local database and identity, i want identity without hyphen how dow i that?
|
|
|
|
|
Identity? Hyphen? What hyphen??
Again, you provide absolutely no context to your question.
|
|
|
|
|
|
When you ask a question, you need to consider your audience. We don't know what's on your screen. What are your inputs? What output are you expecting? What are the rules to do the processing?
modified 17-Feb-15 17:36pm.
|
|
|
|
|
I have a table for the client that is
-clientid (identity option is on)
-firstname
-lastname
-phonenumber
-streetname
-housnumber
-zipcode
-city
etc etc
second table is order DataGridView
-orderid (identity option is on)
-clientid (id come from client table in the clientid colom)
-item
-qlt
-price
-total
|
|
|
|
|
I'm out. I've asked so many times for exactly what you're doing and you have failed to answer those questions time and time again.
You're on your own.
|
|
|
|
|
|
IMO, if this is how you behave, he should take it as a blessing that you are no longer involving yourself.
I suggest that you use your intelligence to take a look at your behaviour, and seek out "syntax changes" that will make it functional.
BTW, this is not a discussion. I have said what needed to be said, and will not visit this thread again.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
|
When you write your insert statement, don't attempt to insert a value into the fields that have identities set. Identities are automatically created for you by the database server. If you want to get the value that you created back, you simply use
SELECT Scope_Identity() AS CreatedIdentity immediately after the insert.
|
|
|
|
|
I know I shouldn't, but I just had to upvote that.
|
|
|
|
|
Hell I shouldn't of even posted it! But, I only have so much patience and I've tried asking him for more detail so many times and gotten nothing but a blank stare back.
|
|
|
|
|