如何从另一个作用域访问线程?



这是我遇到问题的代码。我试图停止线程,但我一直得到一个错误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();
} ) );
}
}
}
}

如果在类范围内声明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;
}

最新更新