|
I want to display the status in a ProgressBar when copying large files across the network. I am using FileInfo.CopyTo method within the DoWork Method of the BackgroundWorker class (please see the code below). How am I able to fire events while the copying is taking place to update the ProgressBar. The problem is that the execution enters FileInfo.CopyTo method and does not leave until the process is complete.
Hope this makes sense.
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {<br />
<br />
BackgroundWorker worker = sender as BackgroundWorker;<br />
reached = 0;<br />
fileInfoFrom = new FileInfo(@"C:\Temp\Path1\Test.zip");<br />
fileInfoTo = new FileInfo(@"C:\Temp\Path2\Test.zip");<br />
<br />
<br />
fs = (fileInfoTo.Exists) ? fileInfoTo.Length : 0f;<br />
fileInfoFrom.CopyTo(@"C:\Temp\Path2\Test.zip", true);<br />
<br />
int completed =<br />
(int)((float)fs / (float)fileInfoFrom.Length * 100);<br />
if (completed > reached) {<br />
reached = completed;<br />
worker.ReportProgress(completed);<br />
}<br />
}
-- modified at 12:47 Sunday 4th December, 2005
|
|
|
|
|
Well, the way I'd tackle it would be to implement the File Copy function myself. I could raise events with controlled frequency as I shovel the data from the source file to the new destination file.
Regards,
Rob Philpott.
|
|
|
|
|
Do you know of any examples that I can take a look at?
|
|
|
|
|
Hi,
I've cobbled together an implementation you can use to get you started. Please note this is rough and ready and has no Exception handling in it etc. Ideally, to do the job properly I'd implement a new class and provide BeginCopy , CancelCopy and EndCopy static methods as we are encouraged to do for asynchronous methods.
BTW - because you will launch the copy on a worker thread, make sure you switch thread before attempting to update your progress bar (use Control.BeginInvoke ).
<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using System.IO;<br />
<br />
namespace ConsoleApplication1<br />
{<br />
class Program<br />
{<br />
static void Main(string[] args)<br />
{<br />
FileCopy(@"f:\BTSDev Hard Disk.vhd", @"c:\test.vhd", new UpdateProgressDelegate(RelayProgress));<br />
}<br />
<br />
public static void RelayProgress(int percentile)<br />
{<br />
Console.WriteLine("{0}% complete", percentile);<br />
}<br />
<br />
delegate void UpdateProgressDelegate(int percentile);<br />
<br />
static void FileCopy(string sourceFileName, string destinationFileName, UpdateProgressDelegate handler)<br />
{<br />
byte[] buffer = new byte[1024];<br />
<br />
FileStream fsInput = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read);<br />
FileStream fsOutput = new FileStream(destinationFileName, FileMode.Create, FileAccess.Write);<br />
<br />
long totalLength = fsInput.Length;<br />
long readSoFar = 0;<br />
int percentile = 0;<br />
<br />
handler(0);<br />
<br />
int readThisBuffer = fsInput.Read(buffer, 0, 1024);<br />
<br />
while (readThisBuffer > 0)<br />
{<br />
readSoFar += readThisBuffer;<br />
int newPercentile = (int)((double)readSoFar / (double)totalLength * 100.0);<br />
if (newPercentile > percentile)<br />
{<br />
percentile = newPercentile;<br />
<br />
if (handler != null)<br />
{<br />
handler(percentile);<br />
}<br />
}<br />
<br />
fsOutput.Write(buffer, 0, readThisBuffer);<br />
readThisBuffer = fsInput.Read(buffer, 0, 1024);<br />
}<br />
<br />
handler(100);<br />
<br />
fsInput.Close();<br />
fsOutput.Close();<br />
} <br />
}<br />
}<br />
Regards,
Rob Philpott.
|
|
|
|
|
Thank you, that makes sense. Do you think this method would be slower than the FileInfo or File classes? I am sure thaey use a very similar method within those classes.
Thank you once again. Will be implementing the method.
|
|
|
|
|
Hi,
No problem, glad to be of help
Performace wise I'd expect the Framework methods to have the edge as they use unmanaged Win32 calls behind the scenes (probably the reason asynchronous methods aren't provided for us). One thing you could do if the files you are copying are very big is to increase the size of the buffer from 1KB to say 8KB or more.
Regards,
Rob Philpott.
|
|
|
|
|
I usually use special characters in many Form, in VS.NET i must use Advanced Save to change my Encoding. How i can change VS.NET 2003 to default encoding Unicode UTF 8 for all project? Thanks
Nothing
|
|
|
|
|
Hi all,
I wanted to ask if it is possible to make the combobox only accept values from its dropdown options, because you can just enter some rubbish in the combobox and then I would have to check if the chosen input actually is a valid input(ie one from the options). Is there another way to do this or I would have to validate the input against the options?
Regards,
gamehack
|
|
|
|
|
Yes, you can. Check out the ComboBox.DropDownStyle property.
"we must lose precision to make significant statements about complex systems."
-deKorvin on uncertainty
|
|
|
|
|
Thank you
|
|
|
|
|
My pleasure. Happy coding!
"we must lose precision to make significant statements about complex systems."
-deKorvin on uncertainty
|
|
|
|
|
I was looking at some advanced code for learning experience. Can someone explain why a Dispose method would be used in classes? Is the destructor not good enough?
~RythmMachineApp()
{
Dispose();
}
public void Dispose()
{
if (Mixer != null)
Mixer.Dispose();
System.GC.SuppressFinalize(this);
}
|
|
|
|
|
A Dispose method is used to make the object release any unmanaged resources. If you would put that in the destructor instead, the resources would no be released until the object is garbage collected.
---
b { font-weight: normal; }
|
|
|
|
|
The reason is that you have zero control over when the "finalizer" (as the destructor is called in C#) is called.
If you have a class that has a Dispose method then you are supposed to call it when you are done with any object of that class. The Dispose method would normally close connections to external resources, free up unmanaged objects and so on.
You call Dispose from the finaliser in case the caller of the class did not clean it up properly. It also means that you only have one method where the clean up code resides.
You can have the language automatically called Dispose on objects with an IDisposable interface like this:
using (SomeDisposableObject obj = new SomeDisposableObject())
{
}
Does this help?
My: Blog | Photos
"Man who stand on hill with mouth open will wait long time for roast duck to drop in." -- Confucious
|
|
|
|
|
I have an understanding now. I thought the redundancy with destructor and Dispose was odd, but now i see it is a way to have more control over the NET framework behavior.
|
|
|
|
|
I was looking at some advanced code for learning experience. Can someone go over and explain the weird looking parts of the following code snippets?
SNIPPET #1
What is with the '?' and ':'?
public int GetBufferedSize()
{
return m_Player != null ? m_Player.GetBufferedSize() : 0;
}
lock(this)
{
return m_Playing ? this.Size : 0;
}
SNIPPET #2
What is with the 'this'?
public Track this[int ndx]
{
get
{
lock(m_Tracks)
return (Track)m_Tracks[ndx];
}
}
|
|
|
|
|
?: is the ternary operator that is the equivalent of if/else
a?b:c ==> if(a){b}else{c}
Does this help?
My: Blog | Photos
"Man who stand on hill with mouth open will wait long time for roast duck to drop in." -- Confucious
|
|
|
|
|
|
Forgot the second one.
In the context you have presented this[] creates an indexer method for the class.
My: Blog | Photos
"Man who stand on hill with mouth open will wait long time for roast duck to drop in." -- Confucious
|
|
|
|
|
It's a conditional value. If the value in front of the question mark is true, the first value is used, otherwise the second. It has the same effect as:
public int GetBufferedSize()
{
if (m_Player != null) {
return m_Player.GetBufferedSize();
} else {
return 0;
}
}
redfish34 wrote: What is with the 'this'?
That is the way you declare an indexer for the class.
---
b { font-weight: normal; }
|
|
|
|
|
|
I've found several articles on comparing two bitmaps to see if they are the same, however, they address two images that are the same size. What if I have two images of different sizes and I want to determine if the smaller image resides somewhere within the larger one. This seems like an easy task, but I'm not having any success as of yet.
Any help would be appreciated.
Thanks.
|
|
|
|
|
I've been reading through the projects here on codeproject, but i still don't fully grasp all of this.
I'm writing a simple class that I can use manage application settings in my forms. Note, it is not meant to handle nested elements. There will be one root element "<configuration>" and inside that will be the settings as key/value pairs.
Here's what I've got so far:
class Config
{
private string m_Path;
private string m_Err;
private XmlDocument xmlDoc;
private XmlNode xmlNode;
// The Config constructor - supply the path name to the file, load the document
public Config(string Path)
{
m_Path = Path;
Load();
}
// Load the stored settings into the XmlDocument
public bool Load()
{
try
{
XmlTextReader xtr = new XmlTextReader(m_Path);
}
catch (Exception ex)
{
m_Err = ex.ToString();
return false;
}
try
{
xmlDoc = new XmlDocument();
xmlDoc.Load(xtr);
}
catch (Exception ex)
{
m_Err = ex.ToString();
return false;
}
return true;
}
// Attempt to return the value, given the key name
public string GetValue(string key)
{
// ITERATE THROUGH KEYS, IF FOUND, RETURN THE VALUE, OTHERWISE, return "NULL";
return "NULL";
}
// Attempt to set the value of the given key. If it does not exist, create a new key/value
// Upon creation or modification of the XmlDocument, write the document to the configuration file
public bool SetValue(string key, string value)
{
// ITERATE THROUGH THE VALUES, FIND THE CORRECT NODE
// IF NODE IS FOUND, MODIFY THE VALUE
// IF NODE IS NOT FOUND, CREATE THE NEW VALUE
return true;
}
// Return an arraylist containing all key/value pairs as such: "key:value"
public ArrayList GetAllValues()
{
ArrayList aryList = new ArrayList();
// Finish Me!
// foreach(key k in XmlDocument)
// aryList.Add((string)(key) + (string)(value));
return aryList;
}
public bool WriteFile()
{
try
{
XmlTextWriter xmw = new XmlTextWriter(m_Path);
// WRITE xmlDoc using xmw to m_Path
}
catch(Exception ex)
{
m_Err = ex.ToString();
return false;
}
return true;
}
}
As you can see, the things I don't know how to do are written as comments describing what needs to happen at that particular segement. If somoene can help me out with this, I'd be greatly appreciative. I've been pouring over my C# manuals and the projects online for about 8 hours or so, trying to find a straight forward way to do this, but haven't figured it out yet.
As always, thanks much.
|
|
|
|
|
budidharma wrote: public string GetValue(string key)
{
// ITERATE THROUGH KEYS, IF FOUND, RETURN THE VALUE, OTHERWISE, return "NULL";
return "NULL";
}
You can use the SelectNodes[^] or the SelectSingleNode[^] method on XmlDocument to do that. Give it an XPath expression and it will return you the appropriate nodes. In your case, it will probably look like
xmlDoc.SelectNodes("//nodeName[@key='keyValue'");
assuming the key value pairs are of the form <nodeName key="KeyValue value="Value>
budidharma wrote: public bool SetValue(string key, string value)
{
// ITERATE THROUGH THE VALUES, FIND THE CORRECT NODE
// IF NODE IS FOUND, MODIFY THE VALUE
// IF NODE IS NOT FOUND, CREATE THE NEW VALUE
return true;
}
To modify an existing node, get a reference to it using the above method. Then use the Attributes property and the indexer to get a reference to the attribute and then just set the Value[^] property to the desired value.
You can use the CreateNode[^] method to create a new node.
budidharma wrote: public ArrayList GetAllValues()
{
You can again use SelectNodes, or you can just do a foreach over XmlDocument.DocumentElement.ChildNodes, if it's always going to be the key-value pairs directly under the root.
budidharma wrote: // WRITE xmlDoc using xmw to m_Path
Use the WriteTo[^] method.
I guess you didn't look hard enough, all the details are available in MSDN
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
I would like to know how create a button that can scroll the content of a tabpage.
Thank you for your help
To be
|
|
|
|