如何从另一个范围访问线程?
How do I access a thread from another scope?
这是我遇到问题的代码。我试图停止线程,但我不断收到错误 Use of unassigned local variable 'Listener'
。我不明白为什么它未分配。它是在上层范围内定义的。
应该发生的是,在单击 SetMousePos
按钮(绑定到 SetMousePos_Click
)时,将弹出一个新的迷你表单,其中包含显示用户鼠标在 (x, y) 坐标。但是,关闭迷你窗体后,它会重新打开,但会挂起并冻结迷你窗体和主窗体。我确定这是因为线程被留下 运行.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DesktopApp1 {
public partial class Form1 : Form {
bool KeyPressed = false;
public Form1() {
InitializeComponent();
ClickAmountBox.Value = 0;
IntervalAmountBox.Value = 0;
}
private void SetMousePosBox_Click( object sender, EventArgs e ) {
MessageBox.Show( "This is a tool to get your mouse's position by simply placing it somewhere. Move your mouse to a position and click the spacebar to record its coordinates. The boxes will autofill the values" );
Form PopUpForm = new Form();
PopUpForm.Size = new Size( 250, 250 );
PopUpForm.MaximizeBox = false;
PopUpForm.MinimizeBox = false;
PopUpForm.StartPosition = FormStartPosition.CenterScreen;
Label WaitingLabel = new Forms.Label();
WaitingLabel.Text = "Waiting for spacebar...";
WaitingLabel.Size = new Size( 200, 15 );
WaitingLabel.Location = new Point( 15, 15 );
Label LabelX = new Forms.Label();
LabelX.Text = "Mouse X: ";
LabelX.Location = new Point( 15, 40 );
LabelX.Size = new Size( 200, 15 );
Label LabelY = new Forms.Label();
LabelY.Text = "Mouse Y: ";
LabelY.Location = new Point( 15, 60 );
LabelY.Size = new Size( 200, 15 );
Button OKButton = new Forms.Button();
OKButton.Location = new Point( 15, 90 );
OKButton.Text = "OK";
OKButton.Click += new EventHandler( OkButtonClicked );
PopUpForm.Controls.Add( WaitingLabel );
PopUpForm.Controls.Add( OKButton );
PopUpForm.Controls.Add( LabelX );
PopUpForm.Controls.Add( LabelY );
PopUpForm.Show();
Thread Listener = new Thread( UpdateMouseLocation );
Listener.Start();
void UpdateMouseLocation() {
while( !KeyPressed ) {
try {
Invoke(
new Action(
() => {
LabelX.Text = "Mouse X: " + Cursor.Position.X.ToString();
LabelY.Text = "Mouse Y: " + Cursor.Position.Y.ToString();
}
)
);
} catch( ObjectDisposedException ) {
;
}
}
}
void OkButtonClicked( object sender1, EventArgs e1 ) {
PopUpForm.Close();
// ============================================================================
// ============================================================================
// THIS IS THE ERROR LOCATION
Invoke( new Action( () => {
Listener.Abort();
} ) );
}
}
}
}
如果您在 class 范围内声明 Listener
变量,您的代码应该可以工作。喜欢:
namespace DesktopApp1 {
public partial class Form1 : Form {
bool KeyPressed = false;
private Thread Listener = null;
public Form1() {
并且:
PopUpForm.Show();
Listener = new Thread( UpdateMouseLocation );
Listener.Start();
或者用一个变量来控制执行。这将允许线程干净地结束:
public partial class Form1 : Form
{
bool KeyPressed = false;
private Thread Listener = null;
private bool RunThread = false;
...
void UpdateMouseLocation()
{
RunThread = true;
while (!KeyPressed && RunThread)
{
try
{
Invoke(
new Action(
() => {
LabelX.Text = "Mouse X: " + Cursor.Position.X.ToString();
LabelY.Text = "Mouse Y: " + Cursor.Position.Y.ToString();
}
)
);
Console.WriteLine(i++);
}
catch (ObjectDisposedException)
{
;
}
}
}
void OkButtonClicked(object sender1, EventArgs e1)
{
PopUpForm.Close();
// ============================================================================
// ============================================================================
// THIS IS THE ERROR LOCATION
RunThread = false;
}
这是我遇到问题的代码。我试图停止线程,但我不断收到错误 Use of unassigned local variable 'Listener'
。我不明白为什么它未分配。它是在上层范围内定义的。
应该发生的是,在单击 SetMousePos
按钮(绑定到 SetMousePos_Click
)时,将弹出一个新的迷你表单,其中包含显示用户鼠标在 (x, y) 坐标。但是,关闭迷你窗体后,它会重新打开,但会挂起并冻结迷你窗体和主窗体。我确定这是因为线程被留下 运行.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DesktopApp1 {
public partial class Form1 : Form {
bool KeyPressed = false;
public Form1() {
InitializeComponent();
ClickAmountBox.Value = 0;
IntervalAmountBox.Value = 0;
}
private void SetMousePosBox_Click( object sender, EventArgs e ) {
MessageBox.Show( "This is a tool to get your mouse's position by simply placing it somewhere. Move your mouse to a position and click the spacebar to record its coordinates. The boxes will autofill the values" );
Form PopUpForm = new Form();
PopUpForm.Size = new Size( 250, 250 );
PopUpForm.MaximizeBox = false;
PopUpForm.MinimizeBox = false;
PopUpForm.StartPosition = FormStartPosition.CenterScreen;
Label WaitingLabel = new Forms.Label();
WaitingLabel.Text = "Waiting for spacebar...";
WaitingLabel.Size = new Size( 200, 15 );
WaitingLabel.Location = new Point( 15, 15 );
Label LabelX = new Forms.Label();
LabelX.Text = "Mouse X: ";
LabelX.Location = new Point( 15, 40 );
LabelX.Size = new Size( 200, 15 );
Label LabelY = new Forms.Label();
LabelY.Text = "Mouse Y: ";
LabelY.Location = new Point( 15, 60 );
LabelY.Size = new Size( 200, 15 );
Button OKButton = new Forms.Button();
OKButton.Location = new Point( 15, 90 );
OKButton.Text = "OK";
OKButton.Click += new EventHandler( OkButtonClicked );
PopUpForm.Controls.Add( WaitingLabel );
PopUpForm.Controls.Add( OKButton );
PopUpForm.Controls.Add( LabelX );
PopUpForm.Controls.Add( LabelY );
PopUpForm.Show();
Thread Listener = new Thread( UpdateMouseLocation );
Listener.Start();
void UpdateMouseLocation() {
while( !KeyPressed ) {
try {
Invoke(
new Action(
() => {
LabelX.Text = "Mouse X: " + Cursor.Position.X.ToString();
LabelY.Text = "Mouse Y: " + Cursor.Position.Y.ToString();
}
)
);
} catch( ObjectDisposedException ) {
;
}
}
}
void OkButtonClicked( object sender1, EventArgs e1 ) {
PopUpForm.Close();
// ============================================================================
// ============================================================================
// THIS IS THE ERROR LOCATION
Invoke( new Action( () => {
Listener.Abort();
} ) );
}
}
}
}
如果您在 class 范围内声明 Listener
变量,您的代码应该可以工作。喜欢:
namespace DesktopApp1 {
public partial class Form1 : Form {
bool KeyPressed = false;
private Thread Listener = null;
public Form1() {
并且:
PopUpForm.Show();
Listener = new Thread( UpdateMouseLocation );
Listener.Start();
或者用一个变量来控制执行。这将允许线程干净地结束:
public partial class Form1 : Form
{
bool KeyPressed = false;
private Thread Listener = null;
private bool RunThread = false;
...
void UpdateMouseLocation()
{
RunThread = true;
while (!KeyPressed && RunThread)
{
try
{
Invoke(
new Action(
() => {
LabelX.Text = "Mouse X: " + Cursor.Position.X.ToString();
LabelY.Text = "Mouse Y: " + Cursor.Position.Y.ToString();
}
)
);
Console.WriteLine(i++);
}
catch (ObjectDisposedException)
{
;
}
}
}
void OkButtonClicked(object sender1, EventArgs e1)
{
PopUpForm.Close();
// ============================================================================
// ============================================================================
// THIS IS THE ERROR LOCATION
RunThread = false;
}