|
Hi everybody,
one of the old-but-useful tools we work with collects thousands of large image files (meeting particular requirements) and copies them to a separate place on the network. By now this was done with a batch file processing a filelist from a textfile.
I'm trying to replace the tool by a .NET application, but the copy process seems to be a lot slower than the batch copy. After my approaches to split the copy process to different threads have failed, I'm examining a very simple process using a Backgroundworker:
Private Function BGW_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) As Boolean Handles BGW.DoWork
Dim i As Integer = 0
Dim copyResult As Boolean = False
Dim args As copypathArgs = e.Argument
For Each fl As String In args.FileArray
i += 1
e.Result = i
copyResult = DoCopy(Path.Combine(args.sourceDir, fl), Path.Combine(args.targetDir, fl))
BGW.ReportProgress(i / args.FileArray.Length * 100, fl)
Next
End Function
Private Function DoCopy(ByVal source As String, ByVal target As String) As Boolean
Dim overwrite As Boolean = True
Try
My.Computer.FileSystem.CopyFile(source, target, overwrite)
Return True
Catch ex As Exception
Return False
End Try
End Function
The problem is that copying a complete array of files takes much longer than the old method using a batch file. As a consequence and considering a large amount of files, the users react more or less like "I want my old batch file back" to avoid double (sometimes even triple) copy time.
Is the copy process in .NET really so much slower? Are there any other methods which have a better performance? Any other recommendations?
Thank you
Michael
|
|
|
|
|
this may or may not help: reporting progress is rather expensive; if all you do is deal with a percentage, make sure not to call BGW.ReportProgress() unless the percentage has really changed.
FWIW: I don't like the way you swallow exceptions; you turn them into a bool result, then store it in copyResult (without accumulating) and finally ignore it completely; a copy utility should report about the problems it encounters. In fact, the entire DoCopy method does not make sense at all.
|
|
|
|
|
Thank you for the FWIW (what ever that abbreviation stands for???). It might look even more confused than I actually am because I deleted several lines (e.g. almost everything around the arguments) before posting, trying not to mix the issue of copy performance with any other issues.
The idea of the DoCopy method is to have a false value in case the copy fails, which is then supposed to be reported back to the caller (an Excel sheet). Of course I'd appreciate advice how to solve that in a more elegant way.
Thanks for now
Michael
|
|
|
|
|
"it failed" is not what I want as a result message, as it provides no clue on what caused the failure, hence the user does not know what to do next.
FWIW (Google it!): Simplifying published code you're not happy about often isn't the best way to get things solved.
|
|
|
|
|
Purpose is to Invoke The Parent from a class.
From 'User Control' Parent/Paren form can be accessed.
'Me.Parent 'OR
'Me.ParentForm
'Me.Parent.Invoke(......)
But I want to do above from a class.
I did using following code:
Private Parent As System.Windows.Forms.Control
Public Sub New (ByVal Parent As System.Windows.Forms.Control)
'Any way to access Parent Form From a class without passing Parent as Argument?'<br>Me.Parent = Parent
End Sub Is there any alternative without passing Parent Form as Argument to Invoke Parent's Thread?
|
|
|
|
|
Hi,
each WinForms Control has a Parent property. It gets set when the Control is added to its parent's Controls collection, which cannot happen until after its constructor finishes. Hence, no you can't predict its future parent inside its constructor, but you will get it for free later on.
If the Controls get added in Visual Designer, their parent will have been set at the time your Form loads (use the Form.Load event). If you don't know when the parent is going to be set (e.g. because all things happen dynamically), then you could use the Control.ParentChanged event to your advantage.
|
|
|
|
|
Plz read the following Example. You are right only for ctrl1 Class. But my Question was about Class1.
Is there any way to access Parent from Class1?
'Form1
Public Class Form1
Inherits Form
End Class
'Class1
Public Class Class1
'here I want to access form1. not using frm1.member and not usinig dim ff as new form1, ff.member
'I just want to access that form using me.parent
Sub ParentAccess()
Me.Parent.Text = "It's a compile time Error"
'Error:- Parent is not a member of Class1
End Sub
End Class
'User Control1
Public Class ctrl1
Inherits ComboBox
Sub ParentAccess()
Me.Parent.Text = "Very easy to access but my class1 don't have the statment like Inherits ComboBox"
'No Error:
End Sub
End Class
|
|
|
|
|
You can if you set a reference to the form in Class1 but that is a very bad design, unless Class1 is strictly meant as a helper class for that form. Class1 is not an inherited Control class like ctrl1, so it doesn't have Parent property. You will have to define the Control type property and set the property accordingly.
Beside you won't be able to access to the combobox of the form unless you set it to public, which is another bad design.
|
|
|
|
|
How to get name in FlowLayoutPanel child control when I click him. Control is PictureBox
|
|
|
|
|
In the click handler for the control, you can use:
Dim c As Control = DirectCast(sender, Control)
Dim cName As String = c.Name
But, you're not providing enough detail about what you're clicking on or other details that I fear you may be leaving out.
|
|
|
|
|
I give picture from scaner
Dim img As New PictureBox
......
wiaItem = DirectCast(Marshal.CreateWrapperOfType(wiaObj, GetType(ItemClass)), ItemClass)
imageFilename = Path.GetTempFileName()
....
img.Image = Image.FromFile(imageFilename)
FlowLayoutPanel1.Controls.Add(img)
Dim i As Integer
i = FlowLayoutPanel1.Controls.Count
FlowLayoutPanel1.Controls.Item(i - 1).Name = "snimka" & i
and I want to give picture control name when click over him
|
|
|
|
|
Most often when people ask for a Control's name, they are doing something very wrong. Event handlers get a sender parameter that is much better than a name.
|
|
|
|
|
Hi, I need help displaying a list of items in a combo box. My problem is this, I want to display a name "Drive Time" and when it is selected i want to use the value of the variable "002302" it is like:
Drive Time = 002302
I want to display "Drive Time" and I want to use the value "002302" when it is selected in the combobox. I hope this made sense. I appreciate the help.
Thanks
|
|
|
|
|
It would be best if you created a structure to hold both items as a single datatype, and then you create a List(Of item) and bind the ComboBox to the List(Of T). Then in your ComboBox.SelectedIndexChanged you can reset the textbox Like this
Public Class Form1
Private Structure Items
Private strName As String
Private intID As Integer
Public Property Name() As String
Get
Return strName
End Get
Set(ByVal value As String)
strName = value
End Set
End Property
Public Property ID() As Integer
Get
Return intID
End Get
Set(ByVal value As Integer)
intID = value
End Set
End Property
End Structure
Private lstItems As List(Of Items)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lstItems = New List(Of Items)
For i As Integer = 0 To 5
Dim newItem As New Items
newItem.Name = "Item " & i.ToString
newItem.ID = i
lstItems.Add(newItem)
Next
ComboBox1.DataSource = lstItems
ComboBox1.DisplayMember = "Name"
ComboBox1.ValueMember = "ID"
End Sub
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
TextBox1.Text = CType(ComboBox1.SelectedItem, Items).Name
End Sub
End Class
Hope this helps
Happy Coding
|
|
|
|
|
|
Yes, makes sense.
Why don't you use an ArrayList in conjuction with your ComboBox
and make the indexes correspond to one another?
E.g.
ComboBox1.Items.Add("Drive Time")
ComboBox1.Items.Add("......")
...
Array1.Add("002302")
Array1.Add("......")
...
Public Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
value = Array1.Item(ComboBox1.SelectedIndex).ToString
End Sub
|
|
|
|
|
Thank you! that makes so much sense.
|
|
|
|
|
That is horrible. It was OK in the eighties perhaps, now things get to be handled in an object-oriented way, so turn those things into objects, show one of their properties and use another property.
BTW: that is exactly what ComboBox.DisplayMember and ValueMember properties are for.
|
|
|
|
|
Simia est simia et si aurea gestet insignia.
|
|
|
|
|
I hate to admit it but I just recently learned this. I believe what you are trying to do is display one value and use another that is associated with it for something else.
The easiest way I have seen this done is to use the DisplayMember and the ValueMember properties of the combo box like I said I just figured this out and it has made my life so much easier than the old way we handled it. So in your case you would use.
cboMyCombo.DisplayMember = "Drive Time"
cboMyCombo.ValueMember = "002302"
Msgbox(cboMyCombo.ValueMember.ToString())
I did not compile that code it may or may not work but you get the general idea.
Humble Programmer
|
|
|
|
|
Alas, this won't work, since .DisplayMember and .ValueMember
are string based which refer to a corresponding (table)column name
of the bonded data.
|
|
|
|
|
I think the best solution for this is using an enum
private enum combo_values
Drive_Time = 002302
.....
.....
end enum
this is the code for diclareing an enum. Unfortunataly ths would mean that you would have to use an underscore instead of a space. But I guess the user would not mind. So, once the enum is diclared, you can enter the following code when an item is selected:
myValue=ctype(combo1.text,enum)
if you want make 'combo_values' a variable of your type, you can do it by typing something like,' private enum combo_values as integer '.
and do inform me if it does not work.
|
|
|
|
|
Hello To All,
I want to fill the color in outer area of Arc.
Thanks
If you can think then I Can.
|
|
|
|
|
You have permission.
You're welcome
--edit
My apologies for the answer; if you have a point, a coordinate within the surface that you want to color, then you could use the floodfill[^]-algorithm.
I are Troll
|
|
|
|
|
Can u please explain me what r u trying to say.
If you can think then I Can.
|
|
|
|