|
Hi George,
while you clearly attempted to explain things well, you did manage to confuse me: what is the name of the class holding most of the code shown? and what is inside PenDriveBackup?
are you sure you want a new PenDriveBackup() instance created in your FullCopy() method, which is after all a recursive method?
you might answer these by providing a simple class schematic, or by editing your initial post.
|
|
|
|
|
Okay sorry for not explaining this clearly. My goal is simple really. What I want to achieve is;
1. Detect a USB Insertion (this works fine)
2. Upon detection begin copying the contents from the USB drive onto the hard drive. (this works fine)
3. Update a label control on my form
Now if we call the FileCopying method in the same thread the form can not be updated (the form just freezes as copying is taking place)
To count-act this I went into the Designer View and added a 'BackgroundWorker' control which allowed me to run the FileCopying method in that thread so
that the form is able to be updated. (This works, the copying takes place and the form isn't frozen)
Now as point 3. on my list is to update the control this is what I need to do.
Hopefully this can be explained better in code than words so;
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
CopyObject a = e.Argument as CopyObject;
RecursiveCopy.FullCopy(a.sConfigLocation, a.sourceFolder, a.destFolder, a.sDriveName, a.iniFile);
e.Result = "1";
}
This is the 'BackgroundWorker' control as added before and the RecursiveCopy.FullCopy is called in this function (which is called in another thread).
This works fine, the file copy operation is called succesfully as shown here;
public class RecursiveCopy
{
public static void FullCopy(string sConfigLocation, string sourceFolder, string destFolder, string sDriveName, object iniFile)
{
if (!Directory.Exists(destFolder))
Directory.CreateDirectory(destFolder);
int countFile = 0;
string[] files = Directory.GetFiles(sourceFolder);
foreach (string file in files)
{
string name = Path.GetFileName(file);
string dest = Path.Combine(destFolder, name);
PenDriveBackup myClass = new PenDriveBackup();
myClass.backgroundWorker1.ReportProgress(0, file);
File.Copy(file, dest, true);
}
string[] folders = Directory.GetDirectories(sourceFolder);
foreach (string folder in folders)
{
string name = Path.GetFileName(folder);
string dest = Path.Combine(destFolder, name);
Console.WriteLine("Copying " + folder);
FullCopy(sConfigLocation, folder, dest, sDriveName, iniFile);
}
}
}
public void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string message = e.UserState as string;
fileCopyingLbl.Text = message;
}
So from what I know the ProgressChanged method is there so you can update your Form. So from what I believed should work from calling this method is that
the label will be updated as shown in the code.
If I were to put a MessageBox in the method then I can see that the file names are passed into the method properly.
For example;
public void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string message = e.UserState as string;
MessageBox.Show(message);
fileCopyingLbl.Text = message;
}
Everytime a file gets copied in the RecursiveCopy.FullBackup method it will send the data into that function and I can see the MessageBoxes for each file.
So I know the data is getting sent between the methods correctly just that the label control is not getting updated.
Perhaps I am tackling the problem the wrong way? Maybe with the way I'm calling it?
PenDriveBackup myClass = new PenDriveBackup();
myClass.backgroundWorker1.ReportProgress(0, file);
I hope the information this time is enough to hel you get a grasp of the project I am under-going. Thanks for replying, George.
|
|
|
|
|
Hi George,
you did not really answer the three questions I asked you, however you added a comment which probably points to the main problem:
George Quarton wrote: PenDriveBackup myClass = new PenDriveBackup(); // the PenDriveBackup class is where the form resides.
so you create a NEW form; this new form is not the one you already had and probably are looking at, and it is never shown; it has its own instance of everything, including a backgroundworker and a label; that label now gets updated, which will not do anything on the original form, the only one that is visible.
I was somehow expecting this. As I already said before, creating new things in a recursive method often is a mistake.
BTW: You should be more careful when choosing names; I'd suggest PenDriveBackupForm (normally class names are nouns and most often their name suggests what they really are or represent, here a form; methods on the other hand are best named using verbs as they are doing something).
|
|
|
|
|
Ah! I see. Silly mistake. How would I go about updating the form directly then?
I can not call the backgroundWorker1_ProgressChanged method as its apart of another class and is not able to use the static identifier. (I dont have much experience in c# coming from a scripting language things are a little different)
Thanks again for your help and advice.
|
|
|
|
|
I would organize things a bit differently:
1) simple scheme
1A. have your PenDriveBackupForm as it is, however without the BackgroundWorker, as it does not belong to the form.
1B. have your RecursiveCopy class, with a constructor that creates a single (and private) BackgroundWorker (with the "new" keyword), to be used inside that class only; and give it a Label parameter, which you store in a private class member, so the BGW inside that class can access it.
2) better scheme (more object-oriented; keywords are: delegate, event)
2A. same as 1A.
2B. have your RecursiveCopy class, with a constructor that creates a single (and private) BackgroundWorker, to be used inside that class only; don't give it a Label parameter; give the class a public event of type Action<string> which almost means "function pointer to a function that takes a string and returns nothing". Now let your BGW fire that event.
2C. Add a "SetProgressLabel()" method to PenDriveBackupForm to accept a string and set the Label; then also add a delegate for that method to the public event you provided in RecursiveCopy.
The net result is: RecursiveCopy will execute a method of which it does not know much, and SetProgressLabel() will be called when necessary; the coupling between both classes is minimal, you can change the Label to something else without telling RecursiveCopy at all (which can't be done in the simple scheme).
modified on Monday, December 14, 2009 7:35 PM
|
|
|
|
|
Using SMO with SQL Express 2005, I'm experiencing some frustrating behavior.
I'm using SMO Server and Database classes to script my database using Database.ExecuteNonQuery . The database objects are getting scripted correctly, but I'm having problems re-connecting to the database (using SqlConnection.Open ). I get a SqlException ("System.Data.SqlClient.SqlException: Cannot open database \"MyDatabase\" requested by the login. The login failed.\r\nLogin failed for user 'MyDomain\\MyUser'.\r\n at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)\r\n at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)\r\n at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)\r\n at System.Data.SqlClient.SqlConnection.Open()\r\n at MyCodePath\\DataAccessFactory.cs:line 57")
The problem "goes away" if I just wait before trying to create the second connection e.g. if I use a breakpoint and step through the code it works fine.
I am closing my previous connection (the one where I scripted the database) and everything is sequential on a single (the UI) thread.
I'd hate to have to code some delay or retry logic for something that seems pretty standard.
|
|
|
|
|
It's normal, you may use a connection pool in order to avoid problems of connection.
myConnection.ConnectionString = "Persist Security Info=False;Integrated Security=SSPI;database=MyDatabase;server=MyServer;Connect Timeout=30";
The value is expressed in seconds:
Connect Timeout=30
|
|
|
|
|
That's kind of annoying. I've noticed these types of subtleties even when using standard MS tools like SSMS. My first reaction when something fails is to change some variable of the experiment before trying again, but with SQL Server, a lot of times, you just need to act like a crazy person and try the EXACT same thing expecting different results.
Thanks for your tip, I had managed to workaround the issue, but I might implement this suggestion as well.
|
|
|
|
|
greetings,
for the first time ever im investigating RichTextBox control in C# windows forms. i know i need this control in my app as textBox is to simple for my needs.
i have the followig code:
<br />
using System;<br />
using System.Collections.Generic;<br />
using System.ComponentModel;<br />
using System.Data;<br />
using System.Drawing;<br />
using System.Linq;<br />
using System.Text;<br />
using System.Windows.Forms;<br />
<br />
namespace _19_richtextbox<br />
{<br />
public partial class Form1 : Form<br />
{<br />
public Form1()<br />
{<br />
InitializeComponent();<br />
}<br />
<br />
private void richTextBoxHome_KeyDown(object sender, KeyEventArgs e)<br />
{<br />
if (e.KeyValue == (char)(Keys.Return))<br />
{<br />
richTextBoxChat.AppendText("Home:" + richTextBoxHome.Text + "\n");<br />
richTextBoxHome.Clear();<br />
}<br />
}<br />
<br />
}<br />
}<br />
for the moment i just want whatever is typed in one richtextbox to be displayed on the other richtextbox on hitting return.
the issue is everytime i hit return the data is being transfered to the other control but the first control is left with a carriage return before the cursor. this happens everytime i hit return.
how do i make it stop doing this?
both the controls accept multiline input.
please advise if i need to provide more info.
thank you for your time.
|
|
|
|
|
If you handle the return key and don't tell the OS you have done it, it passes it through to the default handler afterwards. Add "e.Handled = true;" to your code, all will be fine.
[edit]I can't spell "the" correctly - fixed.[/edit]
All those who believe in psycho kinesis, raise my hand.
|
|
|
|
|
thank you for your response. it has solved my problem.
may i introduce you to my new situation?
i would like a way to make the "Home:" part in bold.
i have found very little info on this on my searches. the following are the only actual code that i could understand.
rtb1.Rtf = @"{\rtf1\ansi {\b hello} {\i World}}" ;
richTextBox1.Rtf = @"{\rtf1\ansi This is in \b bold\b0.}";
-----------
im not sure how to proceed with this info. i just want the richtextbox to display "Home:" and "Away:" in bold and be able to handle URLs in text.
please advise what should i specify when searching this potic on google or any reference your could think of would be of great help.
|
|
|
|
|
You seem to have most of what you need there already, but have a look at this[^] - it's in VB, but it's pretty clear.
Just think of rtf as an unreadable HTML file and you are just about there!
All those who believe in psycho kinesis, raise my hand.
|
|
|
|
|
|
Hi
Am i ask a hard question about 4hours ago.
|
|
|
|
|
Your question is indeed tough. You have to wait patiently for an answer by somebody who knows the answer.
|
|
|
|
|
The reason you did not get an answer is because
a) It was a repost.
b) Your original was replied to, and you reposted last time
http://www.codeproject.com/Messages/3302834/Re-backup-database.aspx[^]
c) There are many examples on CP about to achieve what you want to achieve.
CCC solved so far: 2 (including a Hard One!)
37!?!! - Randall, Clerks
|
|
|
|
|
My question was changed.
I asked that how can i backup from database.
I got my answer and check it when my database attach to microsoft sql.
but it is necessary for me to use SQLEXPRESS and that way doesn't work when i add my database to SQLEXPRESS and detach from microsoft sql.
I explain more about 4 hours ago.
If somebody know the answer please help me.
|
|
|
|
|
Does shouting and hassling people work in your company? Because in all the ones I've worked in, it just gets peoples backs up, and (certainly with me) reduces the amount of help given to the minimum they can get away with. Just thought I'd mention it...
All those who believe in psycho kinesis, raise my hand.
|
|
|
|
|
please !
I don't think that i'm shouting or... .
I thought that i used wrong sentence or wrong structure because my first language is not english.
but if i told in bad way , i'm sorry.
|
|
|
|
|
using UPPER-CASE is equivalent to shouting.
|
|
|
|
|
REALLY? I WAS WONDERING WHY MY FRIENDS WENT DEAF WHEN I TURNED MY SCREEN-READER ON
[edit] Never mind, that sounded funnier in my mind.
modified on Monday, December 14, 2009 3:58 PM
|
|
|
|
|
|
Hello,
I'd like to create an array, and have it contain two items (two-dimensional) of two different types.
I believe the best way to do this is create my own type, however, I'm unsure how to handle the need for an array.
For instance, I want to create something that will take in:
SnapShot[i] = ( DateTime DateTime.Now, Int Size );
How can this be done?
Thanks,
Matt
|
|
|
|
|
Why not use a Dictionary?[^]
All those who believe in psycho kinesis, raise my hand.
|
|
|
|
|
Thanks!
This will work for two items.
What can I do if I want to store more items?
Thanks,
Matt
|
|
|
|