|
The easiest way to put it in a background thread is to make sure you have a method signature that take one parameter of type object and then use ThreadPool.QueueUserWorkItem(new WaitCallback(method)) - "method" simply being the name of the method you wish to call.
bool stop;
void method(object dummy)
{
while (!stop)
{
...
}
}
However, be aware that the code in method should not use any references to any controls. By default, doing so will result in an exception. You can make this go away by setting Control.CheckForIllegalCrossThreadCalls to false , but it's not a good practice to do so, I think because the controls aren't designed to be thread-safe. Depending on what you're doing, you may or may not decide that you don't care and just use the controls from the background thread anyway. I've done it many times (in apps for my own use only, where I don't really care if this one day leads to some odd behavior of a button because two threads tried to update it's text property at once, resulting in something weird and maybe beautiful) and I haven't had any problems with it, but there is undoubtedly a good reason why Microsoft decided to disallow this by default.
|
|
|
|
|
I don't know do you want to break immediately, but something like this may help
bool stop = false;
while(!stop)
{
..dosomething
}
or
while(true)
{
if(stop)
break;
}
and on your button_click
{
stop = true;
}
hope it helps
|
|
|
|
|
A bit vague. Is your while loop executing in a background thread? If it's executing on your GUI thread and your not calling Application.DoEvents it won't ever break!
Regards,
Rob Philpott.
|
|
|
|
|
while loop is runnung normally, not in thread.
how can i stop using Application.DoEvents
|
|
|
|
|
Create a boolean member:
private bool _running = true;
In the button click event set it to false:
_running = false;
Make your while loop look like this
while (_running)
{
Application.DoEvents();
}
Regards,
Rob Philpott.
|
|
|
|
|
Problem with this is that there won't be any click events, because it won't check this.
You can better use a thread and in this thread you put your code.
Something like this (out of my head):
private bool _running = true;
public static void main(args[])
{
Thread t = new Thread(threadFunction);
t.Start();
}
public void threadFunction()
{
while(_running)
{
}
}
public void Button1_Clicked(object sender, EventArgs e)
{
_running = false;
}
Don't know if the 'thread' part is correct, the rest is ok
|
|
|
|
|
Actually, its perfectly valid. The Application.DoEvents keeps the message pump pumping and is the way mutitasking used to work in the Windows 3.x world.
Admittedly, I prefer your way of doing it but the gentleman suggested he didn't want to use background threads.
Regards,
Rob Philpott.
|
|
|
|
|
I've never used the Application.DoEvents() function. Didn't even know the existance of it.
With that in my mind, I totaly agree with you.
|
|
|
|
|
I tried using this code for reading excel data using c# :
bt the following part of the code is giving errors and is not being executed....
plz help !!!!
using System;
using System.Collections.Generic;
using System.Text;
using Excel;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string Path = @"c:\gg.xls";
Excel.ApplicationClass app = new ApplicationClass();
Excel.Workbook workBook =
app.Workbooks.Open(Path,0,true,5,"","",true,Excel.XlPlatform.xlWindows,"\t",false,false,0,true,1,0);
Excel.Worksheet workSheet = (Excel.Worksheet)workBook.ActiveSheet;
int index = 0;
object rowIndex = 2;
object colIndex1 = 1;
object colIndex2 = 2;
try
{
while (((Excel.Range)workSheet.Cells[rowIndex, colIndex1]).Value2 != null)
{
rowIndex = 2 + index;
string firstName = ((Excel.Range)workSheet.Cells[rowIndex, colIndex1]).Value2.ToString();
string lastName = ((Excel.Range)workSheet.Cells[rowIndex, colIndex2]).Value2.ToString();
Console.WriteLine("Name : {0},{1} ", firstName, lastName);
index++;
}
}
catch (Exception ex)
{
app.Quit();
Console.WriteLine(ex.Message);
}
}
}
}
the error is at "Excel.Workbook workBook = app.Workbooks.Open" :
Error 1
No overload for method 'Open' takes '15' arguments C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\ConsoleApplication1_trytry\ConsoleApplication1_trytry\Program.cs 16 39 ConsoleApplication1_trytry
|
|
|
|
|
Well, that's saying you've got the wrong number of arguments in the open method. Check the documentation on 'Open'.
Regards,
Rob Philpott.
|
|
|
|
|
Hi All,
Please let me know if we can cast a known type to a generic type...
private static T InitData<T>(T dummyColl, int value)
{
List<SampleData> SampleColl = new List<SampleData> {
new SampleData {
Age = 23,
Name="abc"
}
};
dummyColl = (T)SampleColl;
}
Is there any other way around to get this??
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
It would probably throw an exception if you don't use a Collection type, but try (T)Convert.ChangeType(SampleColl, typeof(T)) . Bear in mind that this will convert the list itself. If you want to convert the objects inside the list, then use SampleColl.Cast<t>()</t>
|
|
|
|
|
It is not very clear from your sample what you are trying to do.
If you are doing this to cast a collection (hence the dummyColl name?), you would probably want to do something like:
private static List<t> CastToDerivedType<t>(List<basetype> list) where T : BaseType
{
List<t> result = new List<t>();
foreach (BaseType item in list)
result.Add(item as T);
return result;
}
</t></t></basetype></t></t>
Try explaining what is your goal first.
|
|
|
|
|
|
Just a note - you should note that this line:
dummyColl = (T)SampleColl;
doesn't do anything to the actual dummyColl being passed to the method.
So this kind of casting at the end of your method doesn't do anything.
|
|
|
|
|
I agree...Actually while working for the solution I've passed the dummyColl argument to the method that's because I thought I can get the T type by using dummyColl.GetType().(But I forgot that, to get Type there is actually 'typeof' exists in .NET )
Also using
veki-peki wrote: dummyColl = (T)SampleColl;
gives me a compiler error!!! Cannot convert List type to T
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
As it stands it won't work as T could be anything and so casting from SampleColl to T may very well not work.
Try this, use 'as':
dummyColl = SampleColl as T;
you'll need (I think) to add a constraint to your generic method
private static T InitData<T>(T dummyColl, int value) where T: class
.. because T might be a value type and you need to constrain it to reference types to use as.
If you're not familiar with constraining generic types and methods have a read up on that - that should help you quite a bit but it's hard to offer advice without knowing what derives from what.
Regards,
Rob Philpott.
|
|
|
|
|
Rob Philpott wrote: T could be anything and so casting from SampleColl to T may very well not work
I agree with you...but at the calling site itself I have confined T for only two data types (as per the requirement). So in my code there is never a chance that T is a value type
Rob Philpott wrote: private static T InitData<t>(T dummyColl, int value) where T: class
I've used this but frankly I don't understand its usage...even with that 'where' clause I'm able to do something like this without any compiler error.
int i=2;
(T)Convert.ChangeType(i, dummyColl.GetType())
So whether I use this constraint or not it throws the error at runtime only.Can you please let me know why is it happening?
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
Spunky Coder wrote: but at the calling site itself I have confined T for only two data types
That's unimportant. The compiler needs to compile your function, and in order to do that it needs to know a bit about T. If it knows nothing about T, it has to assume it could be anything and therefore won't accept your cast. By constraining the function, your telling the compiler something about T, enough for it to be satisfied that the cast will always work. Don't forget your assembly might be used in other projects written by other people- how can you guarantee that they'll call it the correct way?
Spunky Coder wrote: So whether I use this constraint or not it throws the error at runtime only.Can you please let me know why is it happening?
What's the error?
Regards,
Rob Philpott.
|
|
|
|
|
Well, the error is a runtime error. "Cannot convert System.Int32 to List". Here List is the type of T passed to this method.
Even when I don't use the 'where' class, the same runtime error is shown when executing the line
int i=2;
(T)Convert.ChangeType(i, dummyColl.GetType())
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
Well, I'm not sure what the question is here. Of course, you cannot cast an int to a list. They're completely different things.
Steer clear of Convert.ChangeType. You won't get any compile time checking with this and compiler errors are always more favourable than runtime ones.
Regards,
Rob Philpott.
|
|
|
|
|
Hmmm...I was asking for the use of 'where T:class '. Anyhow I got it from google about the Constraints on Type Parameters.
Thanks for the information.
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
But you still didn't say why you are trying to do this? Casting Int32 to a List<> doesn't make much sense, so it is natural that you will get this error.
There may be a better solution to your problem, so try to explain what is the actual problem that got you thinking about casting with generic parameters?
|
|
|
|
|
Hi all,
I'm wondering why C# imposes restrictions on assignments using output parameters that are not otherwise present. Presumably there is some logical reason for it, but I can't think of it.
Assume this code:
public interface SomeInterface { }
class A : SomeInterface
{
public SomeInterface Field;
void foo()
{
Parse(out this.Field);
}
static public void Parse(out A something)
{
something = new A();
}
}
This code will not build - instead, the compiler will inform you that The best overloaded method match for A.Parse(out A)' has some invalid arguments . Since A implements SomeInterface, Field is of course assignable to A, but nevertheless it does not build. If I instead write the code so that Parse returns A and the assignment is done in foo(), it builds without as much as a warning, as it should.
void foo()
{
Field = Parse();
}
static public A Parse()
{
return new A();
}
This causes some minor annoyances for me as I'm using the compiler-compiler Coco/R to generate a parser for a language of my creation. This tool lets me specify the parser by means of what's called an attributed grammar, and the generated code uses the attributes in the grammar and maps them to parameters. What I wanted to do was to use an output parameter for most productions in the grammar, like this:
Term<out term="" t=""> = (. t = new Term(); Factor f; .)
Factor<out f=""> (. t.Mul(f); .)
{
'*' Factor<out f=""> (. t.Mul(f); .)
| '/' Factor<out f=""> (. t.Div(f); .)
}
.
This straightforwardly leads to a generated method for parsing a Term that looks like this:
void Term(out Term t)
{
t = new Term(); Factor f;
Factor(out f);
t.Mul(f);
while (la.kind == 15 || la.kind == 16)
{
if (la.kind == 15)
{
Get();
Factor(out f);
t.Mul(f);
}
else
{
Get();
Factor(out f);
t.Div(f);
}
}
}
My little problem arises because I've modeled Factor as an interface type. I want to be able to later on write a new class that performs some calculation or other, be free to derive this class from any class I wish, and so I've defined a simple interface IScalar { decimal GetValue(); } so that any class implementing it can be used as a factor.
I've modeled arithmetic expressions as a list of terms with + or - between them, a Term as shown above as a list of factors separated by * or /, and a Factor as a number, built-in function of the language, variable, or '(' Expr ')' - this model is sufficient to get correct operator precedence and handle nested expressions correctly.
It's not much of an issue as I can declare the output parameter to be of the interface type (these methods are private and only used internally in the parser after all), but I do wonder why C# imposes this restriction on output parameters. Or even if it really does - I haven't checked the language specification and it could be that it's the compiler rather than the spec that restricts me, though it seems a stretch.
|
|
|
|
|
I've been staring at your bit of code for about ten minutes now. I feel like I should know the answer to this but I'm not sure I do. Essentially I guess it's that .NET can't do upcasting when using Out parameters and an exact type match is required.
Can't you do something with the compiler-compiler not to use this construct. I rather dislike out parameters and try to avoid them? Either that or use a local variable of the correct type then assign the interface type to that?
Regards,
Rob Philpott.
|
|
|
|