|
It will only change character width if you change the font, font size or style, or replace a space with a non-blank character in a proportional font - 'W' is wider than ' ' (and depending on the font you select '.' may be narrower). So in a RichTextBox with
1) 2) the "2)" bit will move left or right if you type over the "1)" entry. Yeuch.
I agree whole heartedly on the lines bit - don't clutter things up!
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
I think that you didnt get me question(i know underline style).
I wanna something like this ?
<a href="">http:
|
|
|
|
|
the example in your original post seems quite doable in WordPad, and hence with underlining only.
The link you provided now is defective as well as suspiciously long and complex.
|
|
|
|
|
This[^] is a 'proper' link in case you're interested
|
|
|
|
|
proper it is; is it somehow related to the original question as well?
|
|
|
|
|
well I dont see how he could hope to acheive that using a rich text box.
I think he's just after some kind of lined page effect that responds to the selected Font height. This is probably doable (measuring string sizes in GDI+ ) but more work than I'm prepared to do to experiment as it's not something I'd ever use!
|
|
|
|
|
I haven't done multi-threading before, so I need a bit of help with this.
I have a form with a button. When user clicks on the button for the first time, a recursive function is called. When a certain condition in the function is true, I want the function to wait where it's at for the next button click.
An example:
void ButtonClick(object sender, EventArgs e)
{
if (running)
{
}
else functionCall(0);
}
void functionCall(int num)
{
if (num % 2 == 0)
{
displaySomething();
}
functionCall(num + 1);
}
How would I do this? If I understand correctly, I have to create a class for the thread that's going to run the recursive function. The second thread should wait for the main thread (Monitor.Wait(MainThread???)) to give a pulse, but how would I define the main thread?
modified on Monday, September 6, 2010 2:37 PM
|
|
|
|
|
A simpler solution would be to use a BackgroundWorker object to start the thread off and then use the Monitor object as you specified.
|
|
|
|
|
Thanks for the reply. BackgroundWorker class seems better for my situation, but I still don't really know what I'm doing. Here is what I tried as a test, but it gives me synchronization error.
public partial class Window : Form
{
bool running = false;
BackgroundWorker worker;
int num = 0;
public Window()
{
InitializeComponent();
this.button.Click += new EventHandler(ButtonClick);
}
void ButtonClick(object sender, EventArgs e)
{
if (running)
{
Monitor.Pulse(this);
}
else
{
running = true;
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(Work);
worker.RunWorkerAsync();
}
}
void Work(object sender, DoWorkEventArgs w)
{
++num;
label.Text = num.ToString();
Monitor.Wait(this);
Work(null, null);
}
}
Also, the function Work should have additional parameters, but this is not possible, because DoWork event requires only object and DoWorkEventArgs and nothing more. Would calling another function from function Work (and adding Wait statement to that function) work properly?
Thanks in advance!
|
|
|
|
|
I would personally use the AutoResetEvent class instead of Monitor. I'm not sure if I understand your problem correctly, but the WaitOne() and Set() methods of AutoResetEvent might do exactly what you need.
|
|
|
|
|
Thanks! Surprisingly (since I didn't really add much), the code below works alright. However, I had to set the BackgroundWorker to sleep, otherwise the recursive function "skips" if user clicks the button multiple times really fast. Anyway to fix this? Also, am I doing this whole thing the right way?
void ButtonClick(object sender, EventArgs e)
{
if (running)
{
trigger.Set();
trigger.WaitOne();
label.Text = data.ToString();
}
else
{
running = true;
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(Work);
worker.RunWorkerAsync();
trigger.WaitOne();
label.Text = data.ToString();
}
}
void Work(object sender, DoWorkEventArgs w)
{
recursive(0);
}
void recursive(int num)
{
if (num % 4 == 2)
{
data = num;
trigger.Set();
trigger.WaitOne();
Thread.Sleep(1);
}
recursive(num + 1);
}
Thanks again for the help!
|
|
|
|
|
Typically, when working with a thread, the thread expects a single object. In order to pass multiple values across, a common solution is to create a custom class that wraps the values and pass that instead. Now, another point - I wouldn't lock on this - use a static lock object instead, try:
private static readonly object _syncLock = new object(); Then you just lock on that object, i.e.
lock (_syncLock)
{
Monitor.Pulse(_syncLock);
} Finally, don't attempt to update a control property from a thread - WinForms uses STA, so you have to invoke back onto the UI thread and set it there.
|
|
|
|
|
Use of AutoResetEvent is good idea by using Set and Waitone methods.
You will require two instance of AutoResetEvent, one is for triggering condition(in your case button click) and other is for waiting for triggering.
Have you ever heard about producer/consumer pattern? Your problem can be easily solved by using this pattern. This pattern can be implemented in conditions where you have one thread producing the data and other thread consuming it. I cant make it out from your example whether the background worker is producing data or not (but i am sure it must be).
I would suggest you to go and search for this pattern you will get many good articles describing this pattern.
some of them are
www.albahari.com/threading/part2.aspx
Producer/Consumer Implementation Using Thread,Semaphore and Event
I hope this helps you to solve your problem
oops...I forgot to mention that recursive is not required if you use the above pattern use while(someflag){} instead.
Best Regards,
AD
|
|
|
|
|
Solution on: http://www.sendspace.com/file/f4pcjo
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_tw = new ThreadingWrapper(this);
}
private ThreadingWrapper _tw;
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
_tw.ButtonClicked();
}
public void SetText(object o)
{
string text = (string)o;
label1.Text = text;
}
public void WaitingOnClick(object o)
{
label1.Text += " - WAITING";
button1.Enabled = true;
}
}
public class ThreadingWrapper
{
private AutoResetEvent _are = new AutoResetEvent(false);
private bool _waiting;
private Form1 _form;
public ThreadingWrapper(Form1 toControl)
{
_form = toControl;
}
internal void ButtonClicked()
{
if (_waiting)
{
_waiting = false;
_are.Set();
}
else
{
ThreadPool.QueueUserWorkItem(new WaitCallback(functionCall), 0);
}
}
private void functionCall(object p)
{
int num = (int)p;
Thread.Sleep(500);
_form.BeginInvoke(new WaitCallback(_form.SetText), num.ToString());
if (num % 10 == 0)
{
_form.BeginInvoke(new WaitCallback(_form.WaitingOnClick), "");
_waiting = true;
_are.WaitOne();
}
functionCall(num + 1);
}
}
Let me know if you need abort functionality... and I'm also open to any suggestions on how to improve code... always love to learn something new.
|
|
|
|
|
If you want to eliminate _waiting field in ThreadingWrapper class you should probably use _are.WaitOne(int timeout) overload instead of if(_waiting).
However, first make sure that you understand what current code is doing... and then try eliminating _waiting as a practice.
|
|
|
|
|
I'm using my own thread now, because I've read that ThreadPool should be only used for short operations. I replaced the waiting flag with ThreadState, so I managed to eliminate _waiting. I set the thread's IsBackground property to true, so that it gets aborted on exit.
But I want to abort the thread early myself in certain situations and I've read that using Abort() method isn't a wise thing to do. The only other way that I can think of is to create a flag, which is checked after each function call. If true, the function will return. The function gets 52 calls deep at most, usually around 10 calls deep.
However, I don't know if this will really "destroy the thread", or will the thread just be stopped. Will creating a new ThreadingWrappper object (to the same variable) destroy the thread?
Thanks in advance!
|
|
|
|
|
Thread should be created in situations when you need to control the flow of the thread (although, as you also read Abort is not a good idea) and you are not creating bunch of threads at once. If you wish to see for yourself most "common sense" benchmark for this situation try following code:
private void benchmarkThread()
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
Thread t = new Thread(foo);
t.Start();
}
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
}
private void benchmarkQueue()
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(foo));
}
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
}
private void foo(object o)
{
}
private void button2_Click(object sender, EventArgs e)
{
benchmarkThread();
}
private void button3_Click(object sender, EventArgs e)
{
benchmarkQueue();
}
In my case I get around 5000 ms for Threads and 23 ms for Queue... so winner is more than clear. The reason why this difference is so big is that there are bunch of things that need to be done just so you can get a Thread. And ThreadPool is nothing more than a Pool of Threads that are pre-created for your application context.
So - conclusion or why I have started telling all this - if you have pretty good design/understanding of your code and KNOW how many threads you'll be spawning (be sure to understand that things like Form.BeginInvoke also use ThreadPool!!)... and that number is less then a number of Threads pre-created in ThreadPool (default is 25 I believe; you can influence this number) - then definitely go with ThreadPool.
Recommendation you've read is there because in bigger teams/on bigger projects often people carelessly use ThreadPool. So, situations in which requests come faster than they are processed arise, and then you see large memory/CPU increase of your app; because if all 25 threads of ThreadPool are doing something new QueueUserWorkItem requests will be - of course - queued. If your application can eventually process all requests and recover, everything will be fine; however if requests come faster then they are processed for a long time - you are eventually in some serious trouble (if you can't resubmit requests, app will lose all of them when it eventually crashes because of OutOfMemory). Notice that using Threads manually in this situation isn't silver bullet - just you will probably run out of resources much more quickly / problem will be more obvious.
Finally, using Thread.Abort - I understand you. I'm the one that also holds reference to the thread and then fires Abort... who gives a damn when it works in most cases . However, if you want to know on why it's not a good practice - go here[] (some of the explanations are really good).
|
|
|
|
|
Thanks, I think I understand ThreadPool a bit better now, but I still have some questions:
-Should I worry about the limit of 25 threads or will ThreadPool remove finished ones when the program queues 26th+ thread?
-Is there any safe way to abort/stop a thread from ThreadPool, such as with a flag within the function, so that it gets aborted at the right time?
I have 3 different functions to work on a separate thread, so I basically just need 3 different threads (not counting the STAThread and BeginInvoke threads). The functions can be launched any number of times though (but only one instance at the time), so the finished WorkItems should be removed if there's no way of reusing them.
Thanks in advance!
modified on Friday, September 10, 2010 4:59 AM
|
|
|
|
|
You probably found answer by now, but:
1. Threads are automatically recycled when they finish performing work assigned to them (exit outside method)
2. Not as far as I know - you can't say from outside: "Hey, turn off Thread #23". But inside method you can look for certain switches/flags (class bool parameter for example) and have some condition like:
if (flag)
return;
|
|
|
|
|
Thanks, that's great. Heading to MSDN now to get some understanding about ThreadPool.QueueUserWorkItem and WaitCallBack... Thanks again!
|
|
|
|
|
i just configure win task scheduler in one server that it will run a exe file at specific time but the problem is win task scheduler invoking the exe file many times. suppose when someone connect to that machine over the vpn & remote desktop then suddenly win task scheduler calling that exe. so as many time a user is connecting that server over the vpn some time that exe is calling by win task scheduler. so i just could not understand this behavior of win task scheduler.
so please tell me how to prevent win task scheduler to call exe before the setting time if many user connect to that server over the vpn. i need solution......very urgent.
thanks in advance.
tbhattacharjee
|
|
|
|
|
Tridip Bhattacharjee wrote: so please tell me how to prevent win task scheduler to call exe before the setting time if many user connect to that server over the vpn.
This has absolutely nothing to do with C#. Try posting this in the infrastructure[^] forum.
|
|
|
|
|
I AM STUDENT OF BSCS AND MY FINAL PROJECT IS NOW STARTED. MY FINAL PROJECT IS ABOUT ICMP CONTROLLING SYSTEM.PLZ HELP ME ABOUT THIS PROJECT.
TAHNXXXXXXXXXX
|
|
|
|
|
STOP SHOUTING!
All uppercase is considered as shouting on the internet. And rude.
All lowercase is considered childish.
Also, learn to spell. "PLZ" is not a word. You have a keyboard. Find the vowels. Use them.
"TAHNXXXXXXXXXX" is not, has never been, and will never be, a word. It's not even close to a word.
Now. the question:
What question? Are we supposed to hack into your PC and work out what your problem is? Read your mind? Or just guess?
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|