|
This may be of help for referencing items on a separate thread:
Create an extension method to invoke items:
Module Extensions
<Runtime.CompilerServices.Extension()> _
Sub SynchronisedInvoke(synchMe As ISynchronizeInvoke, action As Action)
If Not synchMe.InvokeRequired Then
action()
Else
synchMe.Invoke(action, New Object() {})
End If
End Sub
End Module
Then you can reference the item on the other thread with the use of a lambda:
lblMessage.SynchronisedInvoke(Sub() lblMessage.Text = "Hello World")
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
|
|
|
|
|
Sorry for responding late. My A/C went out last night, and I need to get a window unit in for temporary use. In the meantime, it is 91degF inside my home and I can only use my laptop for brief stints, that with a cooler pad underneath. My desktop computer needs to stay shut down.
|
|
|
|
|
Hi
Can some one help. I'm trying to run the following script but nothing happens
Option Explicit
Public objShell
dim in = "C:\test3.pdf"
dim out = "C:\test4.ps"
set input = in
set output = out
Set objShell = WScript.CreateObject ("WScript.shell")
objShell.run "c:\pdftops.exe -nocrop -noshrink -level3 %input% %output% "
|
|
|
|
|
First, I assume you have run the pdftops.exe file with the defined inputs from a command prompt and it worked correctly.
Having said that, are you sure the input and output parameters are even being passed to the command line?
My suggestion, build the command line and replace the input/output parameters with the actual equivalents.
sCommand = "c:\pdftops.exe -nocrop -noshrink -level3 " & in & " " & out
objShell.run sCommand
|
|
|
|
|
Of course it doesn't work. The command line you ran was exactly:
c:\pdftops.exe -nocrap -noshrink -leve3 %input% %output%
VBScript does NOT do "automatic" variable replacement in strings. A string it treated as literal. The contents are not modified by what is in the string.
|
|
|
|
|
Further to the other comments, SET in vbscript doesn't set an environment variable; it assigns the reference-type value on the right-hand side to the variable on the left-hand side. Since you've specified Option Explicit and you haven't declared the input or output variables, this should fail.
http://msdn.microsoft.com/en-us/library/4afksd44%28v=vs.84%29.aspx[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
1. in is a keyword. Do not use it.
2. Write the strings something like this...
objShell.run "c:\pdftops.exe -nocrop -noshrink -level3" & input & " " & output
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
Hi, all.
Once again, vb.Net shows how convoluted it can be. Or I'm just stupid.
Assume I have a background thread running. Then, if in the Immediate window, I type in
?m_Thread.ThreadState.ToString
I get back, "Background".
But if I first assign ThreadState to a string variable:
Dim ThreadState_str As String
ThreadState_str = m_Thread.ThreadState.ToString
and type in
?ThreadState_str
I get back:
"Background, WaitSleepJoin"
What is going on here?!
|
|
|
|
|
ThreadState is an enumeration. In the first case, the thread has the IsBackground set, which shows up at Background at the Thread.ThreadState property.
In the second state, the thread is blocked by a wait or join.
Such behavior of the ToString method is due to the FlagsAttribute[^] and the Enum.ToString method[^].
See
ThreadState@MSDN[^] for more details.
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
Thanks, Amitosh.
Seems awfully convoluted. But that's Microsoft, I guess.
|
|
|
|
|
You should not rely on the string representation of an object they are likely to change. You should evaluate the values.
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
That's what is annoying about it. When you take the string representation of an object at any given moment via the ToString method, nothing should change in that moment, and it should be valid as a value. For in that moment, you pulled out a piece of information that in many cases will be used immediately. If vb allows the printing of a value from ThreadState, then that should be the same thing as "printing" it to a string which is nothing more than a storage spot for the same thing. It should be, anyway.
|
|
|
|
|
Schrodinger's cat... the very act of observing the sate can chance the state.
|
|
|
|
|
It makes complete sense and is not convoluted at all. By the way, it's not VB doing it, it's Visual Studios debugger and YOU!
When you stop the app, the debugger stops all the threads in it, therefor modifying their state. But, it's not entirely stopped. When you get the value of a property, the debugger executes the property Get code, so the thread isn't entirely stopped.
As was already mentioned, the act of viewing an object changes it's state!
You're still doing a fair bit of bashing of VB.NET/.NET without trying to understand what's going on under the covers and why.
|
|
|
|
|
Sorry for the frustration showing.
But in an attempt to understand what is going on, here is the way threads should behave the way I understand it. Let's say I have two threads that calculate the results of some equations:
Thread-1 produces 1........2....... 4.......8........16.......32<br />
Thread-2 produces 1.5....1.837....2.49....3.929....7.789....21.737
1. All threads are suspended at time (t). Since Thread-1 is iterating faster than Thread-2, due to simpler equations, Thread-1 makes more progress than Thread-2, by time (t).
2. Since the exact moments that Threads 1 & 2 will be suspe nded will most likely occur asynchronously, this may add further uncertainty as to when Threads 1 & 2 will actually come to a halt. This could result in another complete iteration "slipping through" in either thread. But most likely, each thread will be suspended somewhere in the middle of an iteration. Nonetheless, the output values will not change until an iteration is completed.
3. At time (t + DELTAt), queries are made of the results from Threads 1 & 2. Obviously, both queries cannot be made at the exact same moment. So let's say that Thread-1 was queried first, followed by the query of Thread-2. The results are:
Thread-1.....16<br />
Thread-2.....2.49
4. The queries are NON-suspended actions performed on suspended Threads 1 & 2. Therefore, the results should be the same regardless of when the queries were actually made. Thus, the queries are actions that do not affect the results, once the threads have settled down into their suspended states.
There will be many times when the above timing disparities will not be an issue...I may simply need to see the results at time (t) regardless of any synchronization issues. If I need better synchronization so that the outputs are synchronized at some value of an independent variable, then I can simply stop each thread independently on separate time-dependent bounds.
Beyond that, why, in your understanding, would the queries affect the results?
|
|
|
|
|
First, a little about threading...
Threads are just units of work that are broken up to be run on a processor. There cannot be any more truly asynchronous threads running than there are physical processor cores.
The system has a scheduler which operates in a time cycle, lets call this cycle length "N". In N time, it has to execute all the threads that are available to be run (threads in other states are not scheduled). Each thread is given a time slice, "Y" in which to execute before the processor context switches to another thread. Any unused time is given to the system process which is just a simple loop (processors always have to be doing something). Unless a thread yields (Thread.Yield or Thread.Sleep), it will process for its entire Y period. Processes that do this are using the most processor resources and you can watch the task manager increase in percent usage when this happens.
So, getting back to your comments:
1) Suspending a thread is simply putting its state in the SleepWaitJoin.
2) The "exact" moment that the thread is (I believe) dependent on what the thread is currently doing. If the threads are in the scheduler but have not been run, then I think they are removed from the scheduler. If the thread is running then the scheduler has to wait until the time period expires or the thread yields to place it in the SleepWaitJoin state. So yes, another iteration can "slip" through while this process happens.
3) Queries happen at exactly the same moment according to the threads, this is because the thread executing the query is reading data in a thread that is suspended (one thread is running at a time). This doesn't mean however that you will get the results at the same time, again the thread could yield while reading data and you will get results at different thread times.
4) Again, the results may be different depending on how and when the scheduler interrupts the thread. Even your main thread is a thread, and its scheduled like all the rest of them.
What you are really trying to do is synchronize data between threads, (Thread 1 to main thread and Thread 2 to main thread). You should not rely on when a thread suspends to do this, you need to implement your own synchronization. Luckily there are things like Mutex's, AutoResetEvent, etc that you can use cross-thread to make one thread wait on your main thread to say "go ahead, continue".
|
|
|
|
|
Ron and everyone, thank you for your replies. I think the last post is pretty much what I am saying in my hypothetical example that Ron responded to. But in going back over what everyone has said, I still don't see how, once a thread is suspended and queried, that the result should differ afterwards when that very result is then stored in a string variable. The thread is suspended and is not processing any more of its operations.
"When you get the value of a property, the debugger executes the property Get code, so the thread isn't entirely stopped. As was already mentioned, the act of viewing an object changes it's state!"
If the Schrodinger's Cat analogy is used, it means that when a suspended thread is queried, it for some reason then processes at least some more lines of code OTHER THAN the Get property, that could change that value. Get should not be able to allow its thread to process any other code, like any equations that were about to be executed but were halted. But even then, only one query has been made. When afterwards, that result is stored in a string, it has already been "captured" and is simply sitting there, being copied over into the string. Immediately after the query, shouldn't interaction with that thread already have been finished? The query has been made, which means a result has been pulled OUT of the thread. So the result is now isolated from that thread. The thread is no longer involved and can't somwhow reach out of itself to change that returned value. So the string copy should match the query result, exactly. If what you suggest is true (and maybe it is ), that is analogous to taking a digital picture of someone with a camera, and then when you copied that image over to your harddrive, it changed into a picture of someone else!
|
|
|
|
|
I'm not going to get into this any further because you're beating a dead horse.
But, to add to the description that Ron just posted, in your description, you're ASSUMING that both of your background threads are running at the same time. This is NOT the case! Both threads, MAY be running, or one thread will run and the other won't be, or neither of them will be. Oh, and you're also assuming that threads will run in the order created. None of this is true. Threads can run in any order, for any amount of time, not necessarily the exact same size timeslice.
Normally, the only time you ever look at ThreadState is when you're waiting for it to spin up or waiting for it to end. That's it. Any other use is not reliable as a synchronization method.
|
|
|
|
|
Hi.
I have encountered a peculiar problem with modules that I have never seen before.
Here is a very simple example to demonstrate my point:
Module Module1
Dim x as integer = 1
End Module
Module Module2
Dim y as integer =2
End Module
Private Sub Form_Load(bla, bla, bla)
Me.Text = Str(x+y)
End Sub
When the program runs, both modules are automatically initialized so that the result is the value "3" getting sent to the form.
Up to now, I have never had a problem with modules not getting initialized. But in a new project I am working on, one gets initialized and the other does not. One of them simply does not get recognized. Adding Public to both/either does not help.
Does anyone have an idea as to the kinds of things that can cause this to happen?
Many thanks!
|
|
|
|
|
treddie wrote: But in a new project I am working on, one gets initialized and the other does not. Modules are initialized on first use, and the compiler has no incentive to change that behaviour. It should act as a static class does in C#.
treddie wrote: Does anyone have an idea as to the kinds of things that can cause this to happen? Check your usings; is there any "Module2" in the other namespaces? If there is, then it might be calling the wrong module.
Further, those x and y values should be prefixed with their module-name, to ensure that they're taken from that module (and not some other "global" function called "x").
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Eddy Vluggen wrote: Check your usings; is there any "Module2" in the other namespaces?
No, no others.
Eddy Vluggen wrote: Modules are initialized on first use, and the compiler has no incentive to change that behaviour.
OK, I think I see what you mean. The form_load procedure is referencing two variables with each declared in each module. Since they are both referenced in the form_load procedure, both modules initialize. But when I change the variable in module2 to "z" instead of "y", there is no reference for it in the form_load, so the compiler deems module2 uneccessary at the present time. At least a test of this confirms it in principle.
Eddy Vluggen wrote: those x and y values should be prefixed with their module-name
That part I knew about...I was just making a very simple demo which was not "safe".
|
|
|
|
|
hi all,
I have a code that get data from database into a datatable. My datatable is bind to datagridview without problem. I challenge is that i want user to perform some conditional formatting like alternate column color, automatically format this datatable adding image header, icon indicators (like what we have in excel). Then user will be allowed to export the datagridview to excel with all formats preserved.
Any help will be appreciated.
Tunde
Tunde
|
|
|
|
|
Member 4624169 wrote: Any help will be appreciated. There are some articles that show how to format a datagridview. There's probably also some articles on exporting to Excel. Most of them will focus on data - the DGV is exactly that - a gridview. Conditional formatting in a DGV will require code, where Excel will expect markup.
Member 4624169 wrote: Any help will be appreciated. Anything specific you want to know besides these general pointers?
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Hi, I need to be able to list all folder, sub folders and files for my application by using a ecurrsive loop how do I do this?
So far I have
Imports System.IO
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim AppPath As String = Server.MapPath("~/")
ProcessDirectory(AppPath)
End If
End Sub
Protected Sub ProcessDirectory(ByVal DirPath As String)
Dim Dirs() As String = Directory.GetDirectories(DirPath)
For Each Dir As String In Dirs
Dim tvwRoot As TreeNode = New TreeNode()
If Dir.Substring(Dir.LastIndexOf("\") + 1) <> "App_Code" And Dir.Substring(Dir.LastIndexOf("\") + 1) <> "Bin" And Dir.Substring(Dir.LastIndexOf("\") + 1) <> "Files" Then
tvwRoot.Value = Dir.Substring(Dir.LastIndexOf("\") + 1).ToString
Dim Files() As String = Directory.GetFiles(Dir, "*.aspx")
For Each File As String In Files
Dim tnChild As TreeNode = New TreeNode()
tnChild.Value = File.Substring(File.LastIndexOf("\") + 1).ToString
tvwRoot.ChildNodes.Add(tnChild)
Next
TreeView1.Nodes.Add(tvwRoot)
Dim SubDirs() As String = Directory.GetDirectories(Dir)
For Each SubDir As String In SubDirs
Dim tvwSubFolder As TreeNode = New TreeNode()
tvwSubFolder.Value = SubDir.Substring(SubDir.LastIndexOf("\") + 1)
tvwRoot.ChildNodes.Add(tvwSubFolder)
Dim SubFiles() As String = Directory.GetFiles(Dir, "*.aspx")
For Each File As String In SubFiles
Dim tnChild As TreeNode = New TreeNode()
tnChild.Value = File.Substring(File.LastIndexOf("\") + 1).ToString
tvwSubFolder.ChildNodes.Add(tnChild)
Next
Next
End If
Next
End Sub
|
|
|
|
|
A WinForm-example, you'd have to translate it to a web-environment yourself;
Module Module1
Sub Main()
Using f As New Windows.Forms.Form()
Dim tv As New Windows.Forms.TreeView
tv.Dock = Windows.Forms.DockStyle.Fill
f.Controls.Add(tv)
Dim rootNode As Windows.Forms.TreeNode = tv.Nodes.Add("RootNode")
AddFolder("C:\inetpub\wwwroot", rootNode)
f.ShowDialog()
End Using
End Sub
Sub AddFolder(path As String, parent As Windows.Forms.TreeNode)
For Each folder As String In IO.Directory.GetDirectories(
path, "*.*", IO.SearchOption.TopDirectoryOnly)
Dim folderNode As Windows.Forms.TreeNode = parent.Nodes.Add(
folder, IO.Path.GetFileName(folder))
AddFolder(folder, folderNode)
Next
For Each file As String In IO.Directory.GetFiles(path, "*.*", IO.SearchOption.TopDirectoryOnly)
Dim folderNode As Windows.Forms.TreeNode = parent.Nodes.Add(file, IO.Path.GetFileName(file))
Next
End Sub
End Module
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|