【发布时间】:2012-06-30 11:04:58
【问题描述】:
在 C#.NET 中,我编写了以下简单的后台工作线程:
public class MyBackgrounder
{
public delegate void dlgAlert();
public dlgAlert Alert;
public event EventHandler eventAlert;
Thread trd;
public void Start()
{
if (trd == null || trd.ThreadState == ThreadState.Aborted)
{
trd = new Thread(new ThreadStart(Do));
}
trd.IsBackground = true;
trd.Priority = ThreadPriority.BelowNormal;
trd.Start();
}
void Do()
{
Thread.Sleep(3000);
Done();
}
void Done()
{
if (Alert != null)
Alert();
if (eventAlert != null)
eventAlert(this, new EventArgs());
Kill();
}
public void Kill()
{
if (trd != null)
trd.Abort();
trd = null;
}
}
static class Program
{
[STAThread]
static void Main()
{
MyBackgrounder bg = new MyBackgrounder();
bg.eventAlert += new EventHandler(bg_eventAlert);
bg.Alert = jobDone;
bg.Start();
}
static void bg_eventAlert(object sender, EventArgs e)
{
// here, current thread's id has been changed
}
static void jobDone()
{
// here, current thread's id has been changed
}
}
它只等待 3 秒(完成它的工作),然后引发指定事件或调用委托。直到这里没有问题,一切正常。但是当我观看 'Thread.CurrentThread.ManagedThreadId' 时,我发现它是后台线程!也许这很正常,但我怎样才能防止这种行为?如果您测试 'System.Windows.Forms.Timer' 组件并处理其 'Tick' 事件,您可以看到 'Thread.CurrentThread.ManagedThreadId ' 没有从主线程 ID 更改为其他任何内容。
我能做什么?
【问题讨论】:
-
您的代码没有问题,您只是想了解,对吧?后台工作者 is 在另一个线程中。你在哪里看线程ID?
-
System.Windows.Forms.Timer 使用内部 Windows WM_TIMER 事件并简单地计算滴答数,然后引发 .NET 事件。因此它可以在进程的主线程中工作。您编写的后台工作人员在后台线程中工作(显式通过创建 new Thread()),否则 Thread.Sleep(3000) 会暂停您的所有应用程序。这个在后台线程运行到底有什么问题?
-
@MareInfinitus ,当后台工作对象引发其事件或调用指定的方法时,我看到更改的线程 ID。这意味着我的后台工作人员调用了这些方法。
-
没错,被调用的方法不在后台工作线程中,而是在提供这些回调的线程中。
-
@KubaWyrostek,谢谢。我想解决(更改)后台工作人员的行为,所以以后交互 UI 元素时我会很安全。看来我必须使用本机 Win API 编写后台程序,就像 .NET 的计时器一样,不是吗?但是它如何在不使用线程的独立类中工作!?
标签: c# .net multithreading delegates