如何在不挂起程序的情况下运行无限循环? (c#)
我在 ac# 程序中使用线程,但是线程运行的进程调用另一个函数,该函数具有锁定程序的无限循环,也就是说,如果我单击 Windows 窗体的另一个选项(例如:关闭等)它将不再响应。
这个循环是必要的,而且目前还无法更改。
有没有一种方法可以让我像“后台”一样运行这个循环,并且仍然使用程序中的其他选项,这就是:循环不会阻止进程(我不想使用线程线程内部!)。
Main Program
|
-------Thread(Function)
|
--------In the function ANOTHER
function is called with
an infinite loop inside
(this loop is NOT part of the
Thread function directly)
编辑:添加一些示例代码:
//Here I call the threads
private void userTest_Click(object sender, EventArgs e)
{
for (int i = 0; i < numberOfDevices; i++)
{
try
{
Thread t = new Thread(unused => device(i, sender, e));
t.IsBackground = true;
t.Start();
}
catch (ThreadStateException f)
{
MessageBox.Show("ERROR:" + f); // Display text of exception
}
}
}
线程函数:
//This infinite loop is useless, so it could be deleted. This is not
// the loop I´m talking about
public void device(object i, object s, object f)
{
while (true)
{
if (!killEm)
{
int j = (int)i;
EventArgs g = (EventArgs)f;
BSSDK.BS_SetDeviceID(m_ConnectedDeviceHandle[j],
m_ConnectedDeviceID[j], m_ConnectedDeviceType[j]);
UserManagement userTest = new UserManagement();
userTest.SetDevice(m_ConnectedDeviceHandle[j],
m_ConnectedDeviceID[j], m_ConnectedDeviceType[j]);
userTest.ShowDialog();
}
else
{
userTest.Dispose();
MessageBox.Show("Why don´t u kill it!!?");
break;
}
}
}
在userTest.ShowDialog()函数中是无限循环,我正在谈论
编辑这是 userTest.ShowDialog() 中调用的函数的一部分
private void user_Click(object sender, EventArgs e) {
//THIS IS THE LOOP I´M TALKING!
while (true) {
Keep listening for an user put his finger in the device
...
Do things with that finger template
...
}
。
谢谢。
I´m using threads in a c# program, but the process that the threads runs, calls another function that has an infinite loop that locks the program, this is, if I click another option of the Windows Form (ex: close, etc.) it will no longer response.
This loop in necessary and, by now, can not be changed.
Is there a way that I could run this loop like "background" and still use the other options in the program, this is: that the loop does not block the process (I would not like to use threads inside of threads!).
Main Program
|
-------Thread(Function)
|
--------In the function ANOTHER
function is called with
an infinite loop inside
(this loop is NOT part of the
Thread function directly)
EDIT: Adding some example code:
//Here I call the threads
private void userTest_Click(object sender, EventArgs e)
{
for (int i = 0; i < numberOfDevices; i++)
{
try
{
Thread t = new Thread(unused => device(i, sender, e));
t.IsBackground = true;
t.Start();
}
catch (ThreadStateException f)
{
MessageBox.Show("ERROR:" + f); // Display text of exception
}
}
}
The thread function:
//This infinite loop is useless, so it could be deleted. This is not
// the loop I´m talking about
public void device(object i, object s, object f)
{
while (true)
{
if (!killEm)
{
int j = (int)i;
EventArgs g = (EventArgs)f;
BSSDK.BS_SetDeviceID(m_ConnectedDeviceHandle[j],
m_ConnectedDeviceID[j], m_ConnectedDeviceType[j]);
UserManagement userTest = new UserManagement();
userTest.SetDevice(m_ConnectedDeviceHandle[j],
m_ConnectedDeviceID[j], m_ConnectedDeviceType[j]);
userTest.ShowDialog();
}
else
{
userTest.Dispose();
MessageBox.Show("Why don´t u kill it!!?");
break;
}
}
}
In the userTest.ShowDialog() function is the infinite loop I´m talking about
EDIT This is part of the function that is called in userTest.ShowDialog()
private void user_Click(object sender, EventArgs e) {
//THIS IS THE LOOP I´M TALKING!
while (true) {
Keep listening for an user put his finger in the device
...
Do things with that finger template
...
}
}
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好的;好消息是:您根本不需要线程。这里基本上拥有的是“表单”形式的常规 Windows 窗体组件。这些表单必须保持“活跃”,以响应事件。不过,您不需要创建线程来执行此操作。
关键是 System.Windows.Forms.Application 静态类,它具有根据您的需要量身定制的函数。
此方法允许您的
Form
对象运行,响应事件,而不让调用它的函数继续。它会“阻塞”,让消息泵响应,直到调用Application.Exit()
或其他一些类似的方法。在您的情况下,您想要做的是创建所有表单,然后依次对每个表单调用
Show()
(不是ShowDialog()
),然后最后调用Application.Run()
。这会让你得到你想要的。为了结束你的程序,你需要在某个地方调用
Application.Exit()
来响应某些事情。您有两个可以快速使用的选项:Application.Exit()
表格并关闭它们,首先。例如,您可以使用控件窗体的Form.OnClosing
事件上的事件来执行此操作。Form.OnClosing
事件添加一个事件,用于检查最后一个表单何时关闭(或者是否其中任何一个已关闭?),然后像上面一样调用Application.Exit() 在那里。
一旦您调用
Application.Exit()
,任何打开的表单都应该被拆除(我建议首先手动执行...),然后在主线程中调用Application.Run ()
将完成,允许您的程序继续...我们推测,结束。EDIT: Old answer, for posterity...
您在错误的位置创建新线程。不要为第二个窗口创建新线程。相反,为长时间运行的任务创建一个新线程,并确保将其设置为后台线程,这样即使您关闭窗口它也不会保持活动状态。理想情况下,此循环应该有办法优雅地取消,但你似乎建议你不能碰那个代码......
Okay; Here's the good news: You don't need threads at all. What you basically have here is a regular Windows Forms component in the form of 'forms'. Those forms must be kept 'active', to respond to events. You don't need to create threads to do this, though.
The key is the
System.Windows.Forms.Application
static class, which has a function tailor-made for what you need here.This method lets your
Form
objects run on, responding to events, without letting the function it is called in continue. It 'blocks', letting the message pump respond, untilApplication.Exit()
or some other similar methods are called.What you want to do in your case is create all of your forms, and call
Show()
on each one in turn (notShowDialog()
), and then finally callApplication.Run()
. That gets you what you want.In order to end your program, you need to have a call to
Application.Exit()
happen somewhere, in response to something. You have two options that would work quickly for you:Application.Exit()
, perhaps after cycling through all your userManagement forms and closing them, first. You could do this with an event on the control form'sForm.OnClosing
event, for example.Form.OnClosing
events that checks for when the last one is closed (or perhaps if any of them is closed?) and, like above, callApplication.Exit()
there.Once you call
Application.Exit()
, any open forms should be torn down (I recommend doing it manually, first...) and then your call in the main thread toApplication.Run()
will complete, allowing your program to continue... we presume, to end.EDIT: Old answer, for posterity...
You are creating your new thread in the wrong place.Don't create a new thread for the second window. Instead, create a new thread for the long-running task, and be sure to set it as a background thread, so it doesn't stay alive even when you close the windows.Ideally, this loop should have a way to be cancelled gracefully, but you seem to suggest you can't touch that code...
您应该避免繁忙循环,为什么不能在某些睡眠或暂停系统调用上循环?
You should avoid busy loops, why cannot you loop on some sleeping or pausing system call?
除了这是否是一个好主意之外,您是否尝试过BackgroundWorker?
http://msdn.microsoft。 com/en-us/library/system.componentmodel.backgroundworker(v=VS.80).aspx
Besides the fact if this is a good idea or not, did you try BackgroundWorker?
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=VS.80).aspx
您可以创建一个新线程 http://msdn .microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx
或者
也许使用计时器是合适的http://msdn.microsoft .com/en-us/library/system.timers.timer%28v=vs.71%29.aspx
You can create a new thread http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx
or
Perhaps using a timer would be approperiate http://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.71%29.aspx
这与线程无关 - 即使您从主线程调用这个“无限循环函数”,它仍然会挂起您的程序。
因此,无论是谁编写了这个函数,他/她都必须实现一些机制来阻止它,否则它就毫无用处。没有强制终止线程(Thread.Abort),我建议研究这个机制并在你的线程中使用它。
顺便说一句,这个函数的目的是什么?某种消息处理?
--- 编辑 ---
好的,所以你的“无限循环”实际上是
Form.ShowDialog
。它内部包含一个消息泵,并且以编程方式停止该泵的方法是设置 Form.DialogResult。请注意,您需要将所有 UI 调用编组到正确的线程,如 此所示发布。另外,尝试通过 Application.Run(Form) 运行您的,而不是
Form.ShowDialog
。This has nothing to do with threads - even if you call this "infinite loop function" from the main thread, it would still hang your program.
So, whoever authored this function, he/she mush have implemented some mechanism for stopping it, otherwise it would have been quite useless. Short of forcefully killing the thread (Thread.Abort), I suggest investigating this mechanism and employing it in your thread.
BTW, what is the purpose of this function? Some kind of message processing?
--- EDIT ---
OK, so your "infinite loop" is actually
Form.ShowDialog
. It internally contains a message pump and a way to stop that pump programmatically would be to setForm.DialogResult
. Please note that you need to marshal all the UI calls to the proper threads, as indicated by this post.Also, try running your from through Application.Run(Form), instead of
Form.ShowDialog
.