|
Hello,
Is it really not possible anyway to KILL a running background worker Instantly ? I know it is may be possible by using Thread object but now my application is completely developed using background worker and an user really cant stop a running worker thread as he/she has to depend on race condition and Cancellation Pending property.
Thanks again
Emran
|
|
|
|
|
Hi,
you should not kill/abort threads that may hold resources, open files, whatever. (as
almost all useful threads do).
It is much preferred to use one or more flags that get tested regularly by your thread's code.
Luc Pattyn
|
|
|
|
|
Hi Luc Pattyn,
Thanks a lot for your valuable reply.
Actually I thought there must be a way to abort a background worker safely. Because, when I want to stop a Music which is being played by a player, as a user I should not care how the resources are being used, I know by all means that I want to stop the music playing right a way. My application has some similar situation, but my user is forced to wait for the background worker\s dumb loop where the cancellation flag is checked. And if some reason the background process is stucked and never coming back to check the flag, the user can’t ever stop the process.
As you said I should use Flags. Yes, background worker object provides a flag named "cancellation pending" and I am already using that to check if it should be aborted. But is not there any better solution to stop like a Music player?
Regards
Emran
|
|
|
|
|
This is how I would construct a music player:
have one thread that manages all the music-related resources
have a second thread that does actual sound generation; it gets created when necessary, and
may get killed at all (or some) times, by the manager thread, provided the manager thread is
able to clean up everything. SO in more detail: the user tells the program to stop, the
UI thread tells the manager thread, which in turn, when it feels able to clean up, kills
the sound thread and then cleans up after it.
So in this scheme, two threads cooperate, only one gets killed, being the one NOT responsible
for the resources involved. Now you still must be carefull about synchronizing those threads,
one thing you can not use is locks, since the killable thread is not allowed to hold a lock
that would prevent the manager thread to ever become active again !
Hope this helps.
Luc Pattyn
|
|
|
|
|
Thanks Luc Pattyn,
I understood about killing for Thread opbjects. But there is no method available similar to Abort() or Kill() for BackgroundWorker Objects. I have developed my application using Background worker now I am looking for a way to Stop it instantly.
Is there any way to do that ?
Thanks
Emran
|
|
|
|
|
I havent used BackgroundWorker yet; I have been using some Threadpool threads, but most
often I create my own threads, so I have full control over them, can change their
priorities, and can carefully kill them !
It seems like BackgroundWorker does not provide an immediate kill; you could make one
by getting the working code start with a Thread.GetCurrentThread() but I dont like
that idea very much. For one you are not supposed to kill a Threadpool thread (it isnt yours to
begin with), and I expect the same applies to the BackgroundWorker stuff.
Luc Pattyn
|
|
|
|
|
I am using the following code to do a rotation. This rotates the object about the Point(0, 0). My question is how do I translate in order for the object to rotate about its center point??
Matrix m = new Matrix();
...
m.RotateAt(this.ObjectAngle, this.ObjectRectangle.Location);
g.Transform = m;
this.ObjectRegion.Transform(m);
...
Any help would be greatly appreciated!
Thanks
Theres light at the end of the tunnel, hope it ain't no train.
|
|
|
|
|
It takes one statement:
Image.RotateFlip(RotateFlipType.Rotate180FlipNone);
Luc Pattyn
|
|
|
|
|
The other advice you were offered is wrong ( and weird )
You set a translate transform to make the point of rotation the centre of the image ( so, half the width and half the height ). Then you do a rotate transform to rotate it, and set the translate back again, so it draws where you expect it to.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Christian Graus wrote: The other advice you were offered is wrong ( and weird )
In may simple image processing app, I have one image (a field "private Bitmap image;"),
a paint event handler that contains
Graphics g=e.Graphics;
int w=image.Width;
int h=image.Height;
Rectangle r=new Rectangle(x, y, w*zoomT/zoomN, h*zoomT/zoomN);
g.DrawImage(image,r);
where x, y are globals indicating top left position, and zoomT,zoomN are zooming parameters.
and some controls that trigger image operations; some of them take the form:
image.RotateFlip(RotateFlipType.Rotate90FlipNone);
The above rotate statement gives me a new image that is a rotated copy of the
original. It works just fine, as simple as that. Nothing weird, and no surprises either.
Luc Pattyn
|
|
|
|
|
Luc Pattyn wrote: The above rotate statement gives me a new image that is a rotated copy of the
original. It works just fine, as simple as that. Nothing weird, and no surprises either.
Yes, if he wanted to rotate the actual bitmap, as opposed to drawing it rotated, and he only wanted to rotate 90, 180 or 270 degrees, this would work just fine. It just wasn't an answer to what the OP was asking about.
Christian Graus - C++ MVP
'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert
|
|
|
|
|
Thank you for your help Christian I am going to check it out. It does make sense to me now that the coffee has kicked in!
Theres light at the end of the tunnel, hope it ain't no train.
|
|
|
|
|
This would probably work fine but am writting a cad type app where I need to rotate in smaller increments than 90, 180, 270!
Thank you for you time though!
Theres light at the end of the tunnel, hope it ain't no train.
|
|
|
|
|
Hi.
Can you make the orientation of a Windows Forms ProgressBar to be vertically?
Thanks.
|
|
|
|
|
|
hi big guns. i got a problem how to compare the contents of two are more files. plz plz help me
tahir shah
|
|
|
|
|
please explain what you want. What kind of files, big/small, what kind of result.
is it bool AreIdentical(), or string[] GetDifferences(), or ... ?
Luc Pattyn
|
|
|
|
|
how do i override the behaviour performed when the column header of a datagrid is clicked to sort the rows according to that column? thanks!
I am a SysAdmin, I battle my own daemons.
|
|
|
|
|
I have tried to make a multi-tab browser using some of the information from this[^] post. I have a button that opens up a new tab with a browser in it. But when i go back to the other tab, the browser is gone from that tab! The code i used is...
tabControlBrowser.TabPages.Add("http://www.google.com");
int tabCount = tabControlBrowser.TabCount;
tabControlBrowser.TabPages[tabCount - 1].Controls.Add(webBrowser);
tabControlBrowser.SelectTab(tabCount - 1);
Your help is appreciated!!!
|
|
|
|
|
dsl/fahk wrote: tabControlBrowser.TabPages[tabCount - 1].Controls.Add(webBrowser);
You're moving your webbrowser control between pages, instead of creating a new one
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Hi,
I have to paste a string value to a remote application powered by Citrix. I tried using SendKeys with "(^V)". Then I used the following,
PostMessage(handle,WM_KEYDOWN,Controlkey,IntPtr.Zero);
PostMessage(handle,WM_KEYDOWN,V,IntPtr.Zero);
PostMessage(handle,WM_KEYUP,V,new IntPtr(1));
PostMessage(handle,WM_KEYUP,Controlkey,new IntPtr(1));
This doesn't work either.
Then I tried Sending keys relavent to the pasting value usaing above PostMessage(). i.e. if I have to paste "123" I send three PostMessage calls with 1,2,3 key values respectively. It didn't work too.
Anyway I have pass the value to clipboard. I have the process ID of the remote application too. with these information is there a way to transfer data from clipboard to remote application?
Any help would be great.
Thank you.
Regards,
Sampathg
|
|
|
|
|
Some suggestions:
1.
I dont like "new IntPtr(1)"; you do not intend to send a pointer, so use another function prototype that accepts an int or uint instead of an IntPtr.
(FYI, if you really needed to send a buffer pointer to another process, it should be
meaningful to that process, see e.g. VirtualAllocEx)
2.
WM_KEYUP lParam=repeat count, so it should really be zero, not one.
3.
how did you get the handle ? are you sure it is correct ? did you try some other operation
with it, e.g. a hide/show by sending (showCommand=0/1):
[DllImport("user32", SetLastError=true)]
public static extern uint ShowWindow (IntPtr hWnd, int showCommand);
Cheers
Luc Pattyn
|
|
|
|
|
Hi Luc,
First of all thanks a lot on commenting.
Let me explain you this bit..
I have to paste the value to a window which is a remote application. And the bad thing is this application opens in a remote desktop. I'm not allowed to install or do any change on that desktop. So I only can get the windows handle or the Process Id of the remote desktop window. Then I was able to simulate a mouse click on the relavent textbox. At this point if I use the keyboard "Ctrl+V" for pasting it works. But when I use the code, it doesn't work. With Microsoft.VisualBasic.Keyboard.SenKeys it worked once. But now I get an error saying "you have to enable windows Messaging".
I hope you get a better idea.
Please comment on the isuues.
Thanks a lot.
Sampathg
|
|
|
|
|
Hi Sampathg,
If I understand you correctly, you have a window belonging to some fixed program (the remote desktop app), and when you click a textbox in there, then type ^V, the paste works (and
the pasted stuff probably shows up on the local and the remote PC). Thats what we all expect.
So now you want to programmatically do the same. I guess you need the handle of the textbox
and do the SendMessage stuff. Getting the handle is somewhat tricky; you first need the
handle of the form, then find the textbox in the form's hierarchy of controls.
The only way I know consists of:
- the Win32 method EnumWindows()
remember every control that is or can be visible in the end is a window
remark: it can be nested, just like you can put a button in a panel in a panel in a form.
- a lot of trial and error to identify the right window from the many available
(at first type a known text in the textbox, and try to copy it sending ^C,
you should get label texts and other things you may be able to recognize
I tend to be careful with the code inside the callback method, and do as much as possible
outside it (hence the ArrayList in the example below).
FYI I once wrote:
public delegate bool LP_EnumWindowsProc(IntPtr hWnd, int lParam);
public static ArrayList GetVisibleWindowHandles() {
lock(env) {
list=new ArrayList();
EnumWindows(new LP_EnumWindowsProc(CollectVisibleWindows), 0);
env.log(env.DETAIL1, "There are "+list.Count+" visible windows");
return list;
}
}
private static void CollectVisibleWindows(IntPtr hWnd, int lParam) {
IntPtr ptr=(IntPtr)hWnd;
if (IsWindowVisible(ptr)) {
list.Add(ptr);
}
}
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern int EnumWindows(LP_EnumWindowsProc ewp, object lParam);
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern bool IsWindowVisible(IntPtr hWnd);
Final remark:
you might want to experiment first with a very simple target program that you develop
yourself. But dont expect the handle values to match, I'm pretty sure handle values
are local to the process (but SendMessage will convert them without you worrying about it).
Hope this helps.
Luc Pattyn
|
|
|
|
|
Hi Sampathg,
same message with "ignore HTML tags" !
If I understand you correctly, you have a window belonging to some fixed program (the remote desktop app), and when you click a textbox in there, then type ^V, the paste works (and
the pasted stuff probably shows up on the local and the remote PC). Thats what we all expect.
So now you want to programmatically do the same. I guess you need the handle of the textbox
and do the SendMessage stuff. Getting the handle is somewhat tricky; you first need the
handle of the form, then find the textbox in the form's hierarchy of controls.
The only way I know consists of:
- the Win32 methods EnumWindows() and EnumChildWindows()
remember every control that is or can be visible in the end is a window
remark: it can be nested, just like you can put a button in a panel in a panel in a form.
- a lot of trial and error to identify the right window from the many available
(at first type a known text in the textbox, and try to copy it sending ^C,
you should get label texts and other things you may be able to recognize
I tend to be careful with the code inside the callback method, and do as much as possible
outside it (hence the ArrayList in the example below).
FYI I once wrote:
<pre>
/// <summary>
/// delegate used for EnumWindows() callback function
/// </summary>
public delegate bool LP_EnumWindowsProc(IntPtr hWnd, int lParam);
/// <summary>
/// Gets a collection of all visible windows on the desktop.
/// </summary>
/// <returns></returns>
/// <remarks>The result may include some minimized windows too !</remarks>
public static ArrayList GetVisibleWindowHandles() {
lock(env) {
list=new ArrayList();
EnumWindows(new LP_EnumWindowsProc(CollectVisibleWindows), 0);
env.log(env.DETAIL1, "There are "+list.Count+" visible windows");
return list;
}
}
private static bool CollectVisibleWindows(IntPtr hWnd, int lParam) {
IntPtr ptr=(IntPtr)hWnd;
if (IsWindowVisible(ptr)) {
list.Add(ptr);
}
return true; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< correction !
}
/// <summary>
/// Enumerate all windows, calling a delegate for each of them.
/// </summary>
/// <param name="ewp"></param>
/// <param name="lParam"></param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern int EnumWindows(LP_EnumWindowsProc ewp, object lParam);
/// <summary>
/// Determines whether a window is visible.
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern bool IsWindowVisible(IntPtr hWnd);
</pre>
Final remark:
you might want to experiment first with a very simple target program that you develop
yourself. Window handle values are system wide so your test target program could obtain
and display the handle you are interested in, just so you can check it.
Hope this helps.
Luc Pattyn
-- modified at 22:43 Sunday 14th January, 2007
|
|
|
|
|