|
I tried runnin the code below. I want it to run the Print and dowmload threads as many times as I want.
The threads r properly synchronise with monitor fxns inside the print fxn.
-2 Thread[] myThreads = {new Thread( new ThreadStart (Print)),
-1 new Thread( new ThreadStart (Download))
0 };
1 myThreads[0].Start();
2 Thread.Sleep(50);
3
4 myThreads[1].Start();
5 Thread.Sleep(50);
6
7 foreach (Thread t in myThreads)
8 {
9 t.Join();
10 }
11
12 #region Start thread again (Code not yet working)
13 int cycle = 4;
14 while (cycle-- > 0)
15 {
16 myThreads[0].Start();
17 myThreads[1].Start();
18 foreach (Thread t in myThreads)
19 {
20 t.Join();
21 }
22 }
23 #endregion
24
25 Console.WriteLine("All threads are dead");
When this code gets to line 16 it throws exception that the I can't restart a dead thread
But i want the thread to start again (repeat) it's last job and die when I want it to die. I want to control my codes not the other way round
Can any body help get around this.
|
|
|
|
|
Intead of trying to start the thread again, you can move the code inside the thread function itself. Your thread function should look like
private void Download()
{
int cycle = 5;
while (cycle-- > 0)
{
}
}
In case you want to wait for all threads to Join before beginning the next iteration, you need to implement some sort of signaling (using AutoResetEvent or related classes).
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
|
Hello,
I'm trying to send the HDM_GETORDERARRAY message to my ListView.
The problem is that it requires a pointer to an array to write the indicies in. And I don't know how to pass an array of integers, so that I can read what's been written in it.
Any suggestions?
Thanks in advance!
|
|
|
|
|
I assume your already familiar with using unmanaged code (Introp calls etc.) Try this:
int[] MyArrayOfInts = ...<br />
<br />
fixed(int* p_MyArrayOfInts = MyArrayOfInts) <br />
{<br />
ThatFunction(p_MyArrayOfInts);<br />
}
Good luck.
|
|
|
|
|
OK, but the function prototype is:
protected static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref int lParam)
that is, I have to pass an integer, not an interger pointer...
|
|
|
|
|
iliyang wrote:
that is, I have to pass an integer, not an interger pointer...
The syntax is:
lResult = SendMessage(
(HWND) hWndControl,
(UINT) HDM_GETORDERARRAY,
(WPARAM) wParam,
(LPARAM) lParam
);
where lpiArray is: Pointer to an array of integers that receive the index values for items in the header.
So you do have to pass an array (even if the array is only one element long).
The pointer in the code of my previous post is merely a pointer to the FIRST integer in a row. From there the app can access the next integer, and the next, and so on. It will assume there are iSize integers in a row, starting at the address that is the pointer.
|
|
|
|
|
OK, 10x a lot! It worked finde when I called the function like this:
int[] MyArrayOfInts = ...<br />
<br />
fixed(int* p_MyArrayOfInts = MyArrayOfInts) <br />
{<br />
ThatFunction(*p_MyArrayOfInts);
}
|
|
|
|
|
Huh? That's not a pointer to an array you're putting in the function but the value of the first array element.
Anyhow, I was going to recommend an alternative method. The Interop-call to SendMessage should look something like this:
[DllImport("user32.dll"]<br />
public static extern int SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, IntPtr lParam);
You can get an IntPtr to your array using Marshal.Copy(Int[] source, int startIndex, IntPtr destination, int length) .
I've never used Marshal.Copy before, so if you're decide to try it this way let me know how it turns out.
|
|
|
|
|
Yes, I know that I'm passing the first element of the array,
but I just tried and it worked fine
The second method (with the IntPtr) I found ealier but I didn't
know how to obtain an IntPtr object.
I suppose with the IntPtr is better too.
But how should I get an IntPtr object to copy the array into?
|
|
|
|
|
Just make one:
int[] MyArray = ...<br />
IntPtr MyPointer = IntPtr.Zero;
Marshal.Copy(MyArray, 0, MyPointer, MyArray.Length);
(Note: Don't confuse the marshal-call with the overload Marshal.Copy(IntPtr, int[], int, int) .)
|
|
|
|
|
Nope, Marshal.Copy throws a NullReference exception when passing
a null (0) IntPtr object.
So for now, the "mystical" solution works the best
|
|
|
|
|
You're right, my mistake. I wrongly assumed that the Copy method returns a pointer to the array. On second thought this isn't what Copy does at all. Instead you have to allocate some space yourself using Marshal.AllocHGlobal with the appropriate number of bytes. This gives you a valid IntPtr.
int Nr = ...;
int[] MyArray = new int[Nr];<br />
IntPtr MyPtr = Marshal.AllocHGlobal(Nr * sizeof(int))
Then call SendMessage with MyPtr.
Next use the Copy(IntPtr MyPtr, int[] MyArray, 0, MyArray.Length) method.
Finally use Marshal.FreeHAlloc.
|
|
|
|
|
Well, this time works but the values returned are messed.
But, you know, this does work fine:
_columnOrder = new int[this.Columns.Count];<br />
int size = 0;<br />
<br />
IntPtr pHeader = SendMessage(this.Handle, (int) Win32.Consts.LVM_GETHEADER, 0, ref size);<br />
<br />
SendMessage(pHeader, (int) Win32.Consts.HDM_GETORDERARRAY, _columnOrder.Length, ref _columnOrder[0]);
See the ref _columnOrder[0] in the second SendMessage call
|
|
|
|
|
OK, good luck with your project.
|
|
|
|
|
Im trying to do this:
ResourceManager rm = new ResourceManager("GameRPG", this.GetType().Assembly);<br />
System.IO.FileStream fs = (FileStream)rm.GetObject("outside");
So that i can save the file "outside" (which is stored in the resources) to a folder so that it can be used.
But i just get the message "Specified cast is not valid" (The problem is with the file stream by the way, not the resource manager)
How can i get this to work?
|
|
|
|
|
I assume you have already tried splitting your second line up to
object TheObject = rm.GetObject("outside");<br />
System.IO.FileStream fs = (FileStream)TheObject;
and setting a breakpoint on the first line. Start your app and look in the debug window what type TheObject really is. You'll probably know then what went wrong, or at least get a good clue.
|
|
|
|
|
I have no debug window
Im using sharpdevelop
|
|
|
|
|
My mistake. Try adding
string TheObjectType = TheObject.GetType().ToString();
and writing this string to screen or file.
|
|
|
|
|
No debugger ? Good luck writing anything meaningful.
ResourceManager rm = new ResourceManager("GameRPG", this.GetType().Assembly);
if (rm == null)
MessageBox.Show(""rm is null"); // Obviously not the case, but anyhow....
object o = rm.GetObject("outside");
if ( o == null)
MessageBox.Show("o is null");
MessageBox.Show(o.GetType().ToString()); // Something like this, to find out the type of your object.
System.IO.FileStream fs = (FileStream)o; // This will still throw, but you will know why.
Also, if an object may not be of the type you expect, you can do this:
FileStream fs = rm.GetObject("outside") as FileStream;
if ( fs != null)
{
// it was a filestream
}
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Hi:
Did you check the contents of rm.GetObject("outside") in QuickWatch. I think it is getting evaluation to Null and since Null can not be cast to FileStream class, you are getting
System.InvalidCastException
Deepak Kumar Vasudevan
Personal Web: http://vdeepakkumar.netfirms.com/
I Blog At: http://deepak.blogdrive.com/
|
|
|
|
|
I'm not sure whether the SharpDevelop IDE has a QuickWatch. Anyway, I assumed that the original posted already checked whether the value retrieved by GetObject was not null, because you don't get an "invalid cast" exception when the object is null. In Visual Studio at least, maybe SharpDevelop reacts differently.
|
|
|
|
|
Well thanks guys, i'll try this tomorrow, and i'll download and install a debuger, especially after all the trouble i've had with this.
|
|
|
|
|
After using
<br />
FileStream fs = rm.GetObject("outside") as FileStream;<br />
I thought it had worked but it turns out that the filestream fs is still null.
Any thoughts, also the type of the object is a Byte[]
|
|
|
|
|
Does anyone know how to construct a vectorized (not a rasterized!, i.e. not a bitmap) metafile? I've tried the code below, but all I get a rasterized picture (I suspect it to be a PNG ).
Metafile MyMetafile = null;<br />
using (Graphics RefGraph = Graphics.FromHwnd(IntPtr.Zero))<br />
{<br />
IntPtr RefDC = RefGraph.GetHdc();<br />
MyMetafile = new Metafile(RefDC, new Rectangle(0, 0, MyWidth, MyHeight), <br />
MetafileFrameUnit.Pixel);<br />
RefGraph.ReleaseHdc(RefDC);<br />
}<br />
using (Graphics Graph = Graphics.FromImage(MyMetafile))<br />
{<br />
Brush Br = new SolidBrush(Color.Blue);<br />
Graph.FillRectangle(Br, 0, 0, MyWidth / 2, MyHeight / 2);<br />
}<br />
<br />
MyMetafile.Save(@"c:\temp\test.wmf", ImageFormat.Wmf);
I'm using a screen device context as a basis for the metafile since a reference DC is required when recording a metafile. Maybe that's what's wrong, because this screen DC is rasterized. But I don't know how to get a vectorized DC or if such a thing even exists. Or maybe I'm on the wrong track.
Any help on how to make a vectorized wmf or emf would be helpful.
Thanks.
|
|
|
|