|
Looks a little confusing about the terms, Guffa.
Let me confirm,
1. "A reference variable is a value type, so when it's passed by value (i.e. as usual) it's value is copied" -- we could understand this in context of C++ that the reference is a pointer and the pointer value is copied?
2. "the value of the reference variable is a reference" -- we could understand this in context of C++ that the value of reference is pointer?
regards,
George
|
|
|
|
|
George_George wrote: "A reference variable is a value type, so when it's passed by value (i.e. as usual) it's value is copied" -- we could understand this in context of C++ that the reference is a pointer and the pointer value is copied?
Yes. A reference is actually a pointer, the only difference is that the garbage collector knows that it's a reference so that the memory management "owns" it.
George_George wrote: "the value of the reference variable is a reference" -- we could understand this in context of C++ that the value of reference is pointer?
Yes, a reference variable in C# works like a pointer variable in C++. The difference is that a reference in C# is automatically dereferenced when you use it, so there is no special syntax to dereference it to access the object that it's pointing to.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Thanks for your clarification, Guffa!
regards,
George
|
|
|
|
|
George_George wrote: A reference variable is a value type, so when it's passed by value (i.e. as usual) it's value is copied" -- we could understand this in context of C++ that the reference is a pointer and the pointer value is copied?
See the following code,
static void Main(string[] args) {
StringBuilder sb = new StringBuilder();
PassReferenceByValue(sb);
Console.WriteLine(sb);
PassReferenceAsReference(ref sb);
if (sb == null)
Console.WriteLine("SB is NULL");
Console.Read();
}
static void PassReferenceByValue(StringBuilder sb) {
sb.Append("Something");
sb = null;
}
static void PassReferenceAsReference(ref StringBuilder sb) {
sb.Append("Something");
sb = null;
} When PassReferenceByValue is called, it's call stack will get a local copy of variable "SB". Variable "sb"'s value is a pointer to original StringBuilder instance. So adding a new item to it will add to original object. Making it NULL will affect only the local copy.
When PassReferenceAsReference is called, a reference to the original object will be passed. It is same like we pass a double pointer to a method in C++. So equivalant C++ code would be
void PassReferenceByValue(std::string* str){
str = new std::string;
*str = "This will not come";
}
void PassReferenceAsReference(std::string** str){
*str = new std::string;
(*(*str)) = "Hello";
}
int _tmain(int argc, _TCHAR* argv[])
{
std::string str = "From Main";
std::string* strPtr = &str;
PassReferenceAsReference(&strPtr);
std::cout << (*strPtr) << std::endl;
PassReferenceByValue(strPtr);
std::cout << (*strPtr) << std::endl;
return 0;
} Hope that made sense.
|
|
|
|
|
Thanks Navaneeth,
I like your sample so much!
regards,
George
|
|
|
|
|
|
Thanks Guffa,
1.
Guffa wrote: but the reference to the object is a value type
In practice I agree. But is there any officla document mentioning that?
2.
I agree with your points for a local function call. But for a remote call, like calling a remote web services from client proxy, what is the underlying differences between passing a reference type and passing value type? I think your point of passing just a pointer for reference type is meaningless when dealing with remote call, since the pointer value on one machine is not suitable for another difference machine. Any comments?
regards,
George
|
|
|
|
|
Hello everyone,
One question regarding to the wikipedia page for WS-Addressing for routing,
http://en.wikipedia.org/wiki/WS-Addressing
I am confused about what means "The network-level transport is only responsible for delivering that message to a dispatcher capable of reading the WS-Addressing metadata. Once that message arrives at the dispatcher specified in the URI, the job of the network-level transport is done." -- how do you understand this statement?
regards,
George
|
|
|
|
|
Hi all, I have meddled with threads in the past but I can't claim to really unerstand all the ins and outs of it. I'm stuck with a problem now and I'm hoping someone can point me in the right direction.
I have a custom control that's essentially a Panel onto which PictureBox es can be placed at runtime. The important method in the class is public void AddImage(Image newImage) which creates a new PictureBox , calculates what the size of it should be, what the location of it should be etc. and then adds it to the panel.
So far so good. My problem is that this is a rather time consuming operation and in many cases I have a need to call this member several times in a row to add multiple images to my panel. I'd like to do all of this threaded so that:
1. the main form (containing the custom control) can be updated while images are being added to the control
2. the main form can still accept button clicks and what have you while images are being added to the control
I've tried using System.ComponentModel.BackgroundWorker and System.Threading.Thread but in both cases I've run into problems which might be too lengthy to explain here. I'm not looking for specific code but some advice on how threading can be used in this situation would be appreciated.
Some specific requirements that I have are:
1. I need for the pictures to be added to the control in the order in which I'm sending them with AddPicture .
2. I need to be abe to interrupt the sequence of calls to AddPicture at any stage so that the panel is cleared and a new sequence of calls to AddPicture is started.
Any ideas?
|
|
|
|
|
Creating the PictureBoxes and adding them to the Panel must be done on the main UI thread. So there is a limit to how much work you can offload to a worker thread.
If calculating the size and location is taking a long time, maybe you should look at optimising that code. Modern computers are extremely fast at calculations, so I would be surprised if this was the bottleneck.
You could try allowing the UI to process any messages in it's message queue between calls to AddImage by having a queue of images to add and Posting a custom message to the end of the message queue after each addition. Then the custom message handler would be responsible for actually doing the work one image at a time.
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
Aha, I think you've touched exactly on my problem. I've been adding the PictureBoxes from the worker thread. At first I had exception complaining about it being done from a different thread than the one the Panel was created on so I added code to make it thread safe as per this example on MSDN[^] (looking at the SetText function). Is that incorrect then?
I don't think its the calculating of size and position that really takes up time but rather the instantiating of new PictureBoxes and then the UI work of actually adding them to the Panel . I don't mind it taking a while to add the pictures to the panel, I just don't want the main form to have to wait for it all to finish before it can start accepting button clicks again.
I'll look into this suggestion of using a queue. I think that might just be the first step towards a real sollution, thanks. That said, any further advice would be appreciated.
|
|
|
|
|
The article shows you how to marshal back to the UI thread. Doing it this way is probably just adding overhead to the process.
Do you know how to PostMessage ( http://www.pinvoke.net/default.aspx/user32/PostMessage.html[^] ) a user message and catch it in your override of Control.WndProc ? That's what I would try.
You can also use BeginInvoke , as that posts a message for you, if you don't want to use PInvoke. You have to call EndInvoke , though. I think this is a bit harder, but it is an all managed code solution.
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
OK thanks, I'll have a look into those. A part of me feels that this couldn't be so unusual a scenario that it should be neccesary to turn to unmanaged code or am I wrong?
I think I'll investigate the BeginInvoke and EndInvoke option but I'm a little confused, what exactly is the difference between BeginInvoke and Invoke which I've been using?
|
|
|
|
|
Dewald wrote: what exactly is the difference between BeginInvoke and Invoke which I've been using?
BeginInvoke follows assynchronous fashion calls. So it won't block and will return to the caller immediatly. Invoke blocks the calling thread until the message is handled. Here[^] is an excellent article which talks on this.
|
|
|
|
|
Cool, that is indeed an excellent article. It puts things into perspective but I have to say that I'm getting very frustrated here. I was convinced that I was threading correctly, only to change my mind later that I'm definitely doing it wrong (leading to me posting the question). After reading this article I'm convinced again that I have been doing it right (although I've used Invoke as opposed to BeginInvoke ). The problem is, as convinced as I am that I'm doing it right, my app is still not working so obviously I AM doing it wrong.
I would so appreciate if someone could take the time to look at what I'm doing and point out where I'm getting it wrong. Basically what I'm doing is the following:
I have a member in my main form class
private BackgroundWorker MyWorker;
in the constructor of the main form, after InitializeComponent() I set the worker up as follows:
MyWorker = new BackgroundWorker();
MyWorker.WorkerSupportsCancellation = true;
MyWorker.DoWork += new DoWorkEventHandler(MyWorker_DoWork);
The worker function is simply defined as following:
void MyWorker_DoWork(object sender, DoWorkEventArgs e)
{
SetImages((string)e.Argument, sender as BackgroundWorker, e);
}
The SetImages function extracts the images to be added to my custom control from a DB and calls, for every image, the custom control's AddPicture method which is thread safe by using InvokeRequired and BeginInvoke as described in the article.
Also inside SetImages , the first step at every iteration, before adding an image, is to execute the following code:
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
To add a bunch of images to the control I can now simply call
MyWorker.RunWorkerAsync(someStringValue); the input string determining which collection of images are to be added to the control.
This works perfectly but what doesn't work is when I'm trying to interrupt the worker and call it again with a new input string. The code I'm using for that is as follows:
while (MyWorker.IsBusy)
MyWorker.CancelAsync();
MyWorker.RunWorkerAsync(someStringValue);
The problem is that MyWorker.IsBusy remains true and the little while-loop never exits. I would have thought that checking worker.CancellationPending and setting e.Cancel = true in SetImages should be sufficient to interrupt execution of the thread but it seems not to be.
What am I doing wrong? This is starting to really frustrate me!
|
|
|
|
|
Put Debug.WriteLine in the areas you suspect. It gives you how the code is executing. CancelAsync() just sets the CancellationPending flag to true and won't block the caller.
This might be the reason your loop is going infinite. You can use wait handles, and wait until the worker cancels. In the RunWorkerCompleted event handler, check Cancelled property. If it is cancelled, set the waithandle which will run the next line ie, RunWorkerAsync() . Something like
MyWorker.CancelAsync();
waitHandle.WaitOne();
MyWorker.RunWorkerAsync(someStringValue);
if(e.Cancelled)
waitHandle.Set(); You can use AutoResetEvent as waithandle.
I might be wrong as I haven't tested this. It's a guess. Try your luck.
Dewald wrote: the custom control's AddPicture method which is thread safe by using InvokeRequired and BeginInvoke as described in the article.
AFAIK, controls are usually not made as thread safe. Since you are using BackgroundWorker , you can update controls safely from ProgressChanged event handler.
|
|
|
|
|
Sounds like you're making progress
You should use Invoke not BeginInvoke in AddPicture if you're using a thread. Otherwise, the thread will not block and will loop round adding all the images without waiting for each image to be added.
For the interrupt method, just call CancelAsync once, and then handle the RunWorkerCompleted event.
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
COOL BANANAS!!!! You're my new best friend. Thanks for the help, both of you, I've learned a lot.
|
|
|
|
|
Is there a BinarySearch for IList<T> - or a similar generic BinarySearch?
Couldn't find any besides the (non-generic) Array.BinarySearch
|
|
|
|
|
peterchen wrote: Couldn't find any besides the (non-generic) Array.BinarySearch
There is a generic version of Array.BinarySearch . You can use that to search in IList(T) . Assume you have sorted strings in IList(T) .
int index = Array.BinarySearch<string>(list.ToArray<string>(), "SearchString"); list.ToArray<string>() is an extension method. If you are on .NET 2.0, you won't see this.
Hope it helps
|
|
|
|
|
public static class IListExtensions
{
public static int BinarySearch<T>(this IList<T> list, T item, Comparison<T> comp)
{
if (list == null) throw new ArgumentNullException("list");
if (comp == null) throw new ArgumentNullException("comp");
if (list.Count == 0)
return -1;
return BinarySearch(list, item, comp, 0, list.Count - 1);
}
private static int BinarySearch<T>(IList<T> list, T item,
Comparison<T> comprasion, int start, int end)
{
while (true) {
int i = (end + start) / 2;
int cmp = comprasion(item, list[i]);
if (cmp == 0)
return i;
else if (cmp > 0) {
if (i == end)
return -1;
start = i + 1;
}
else {
if (i == start)
return -1;
end = i - 1;
}
}
}
} Hope this helps .
Greetings - Gajatko
Portable.NET is part of DotGNU, a project to build a complete Free Software replacement for .NET - a system that truly belongs to the developers.
|
|
|
|
|
I take report to show data from table/gridview;
using
private void show_Click(object sender, EventArgs e)
{
SqlDataAdapter da = new SqlDataAdapter("Select * From User_Detail where CDate='" + dateTimePicker1.Text + "' And Username='" + comboBox2.Text + "'", con);
MessageBox.Show(dateTimePicker1.Text.ToString());
DataTable dt1 = new DataTable ();
da.Fill(dt1);
dataGridView1.DataSource = dt1;
if(dt1.Rows.Count!=0)
{
employeereport Emp = new employeereport();
Emp.SetDataSource(dt1);
crystalReportViewer1.ReportSource = Emp;
}
}
that cannot show data related to given date???
all data can be shown but in gridview perfect data can be shown??
Plz tell me where is problem????
|
|
|
|
|
hello every one,
I want to build my database files -data & log files- related to the path of the .exe file of my program that is a setup project,
how to do this?
regards
|
|
|
|
|
|
hi
i must working on StgOpenStorageEx(ole32) bez. i used windows xp
and in www.pinvoke.net
give this defined
DllImport("ole32.dll")]
static extern int StgOpenStorageEx([MarshalAs(UnmanagedType.LPWStr)] string
pwcsName, uint grfMode, uint stgfmt, uint grfAttrs, ref STGOPTIONS
pStgOptions, IntPtr reserved2, [In] ref Guid riid,
[MarshalAs(UnmanagedType.IUnknown)] out object ppObjectOpen);
my problem is in this parameter (ref STGOPTIONS pStgOptions) what i must value give it?????
im searching and am trying
if u can please help me
|
|
|
|