gpt4 book ai didi

c# - 如何杀死 C# 线程?

转载 作者:太空狗 更新时间:2023-10-29 22:28:36 25 4
gpt4 key购买 nike

我有一个线程可以在我们的(旧)SQL 服务器上查找数据。

随着数据的到来,我将信息发布到一个模式对话框中——在所有这些处理过程中,用户不能也不应该做任何其他事情。模态对话框只是为了让他们看到我在做某事,并防止他们同时运行另一个查询。

有时(很少)当代码调用 SQL 服务器时,服务器没有响应(IT 将其关闭进行维护,LAN 线路被切断,或者 PC 不在网络上)或人做查询用完了时间。所以,模态对话框确实有一个取消按钮。

Thread 对象 (System.Threading.Thread) 具有 IsBackground=true

当有人点击取消时,我调用我的 KillThread 方法。

注意:我不能在此类中使用 BackgroundWorker 组件,因为它与某些 Windows Mobile 5 代码共享并且 WM5 没有 BackgroundWorker。

void KillThread(Thread th) {
if (th != null) {
ManualResetEvent mre = new ManualResetEvent(false);
Thread thread1 = new Thread(
() =>
{
try {
if (th.IsAlive) {
//th.Stop();
// 'System.Threading.Thread' does not contain a definition for 'Stop'
// and no extension method 'Stop' accepting a first argument of type
// 'System.Threading.Thread' could be found (are you missing a using
// directive or an assembly reference?)
th.Abort();
}
} catch (Exception err) {
Console.WriteLine(err);
} finally {
mre.Set();
}
}
);
string text = "Thread Killer";
thread1.IsBackground = true;
thread1.Name = text;
thread1.Start();
bool worked = mre.WaitOne(1000);
if (!worked) {
Console.WriteLine(text + " Failed");
}
th = null;
}
}

在我的输出窗口中,我总是看到“Thread Killer Failed”,但从未抛出任何异常。

我应该如何停止线程?

我在以下两个位置找到的最佳相关帖子:

How to Kill Thread in C#?
How to kill a thread instantly in C#?

编辑:

我上面列出的方法似乎有些困惑。

首先,当有人点击取消按钮时,这个例程被调用:

void Cancel_Click(object sender, EventArgs e) {
KillThread(myThread);
}

接下来,当我进去杀死一个线程时,我宁愿不必永远等待线程停止。同时,如果线程仍然处于事件状态,我不想让我的代码继续执行。因此,我使用了一个 ManualResetEvent 对象。它不应该花费整整一秒(1000 毫秒)来停止线程,但每次 WaitOne 方法超时。

仍在倾听想法。

最佳答案

简短的回答:你不知道。通常你通过发出你想退出的信号来做到这一点。如果您正在触发 SQL 查询,请异步执行(请原谅我的拼写),并在必要时取消它。这确实适用于单独线程中的任何冗长任务。

要进一步阅读,请参阅 Eric Lippert 的文章: Careful with that axe, part one: Should I specify a timeout?Careful with that axe, part two: What about exceptions?

编辑:你怎么称呼SQL Server? ADO、TDS、标准/自定义库等... ?该调用应该是异步的。因此:StartOpeningConnection、WaitFor OpeningComplete、StartQuery、WaitFor QueryComplete、Start CloseConnection、WaitFor CloseConnectionComplete 等。在任何等待期间,您的线程都应该休眠。醒来后,检查您的父线程(UI 线程)是否已取消,或发生超时并退出线程并可能通知 sqlserver 您已完成(关闭连接)。

这并不容易,但很少...

编辑 2:在您的情况下,如果您无法将数据库代码更改为异步,请将其设为单独的进程并在必要时将其终止。这样资源(连接等)将被释放。使用线程,情况就不会如此。 但这是一个丑陋的 hack

编辑 3:您应该使用 BeginExecuteReader/EndExecuteReader 模式。 this article is a good reference:这将需要重写您的数据访问代码,但这是正确执行此操作的方法。

关于c# - 如何杀死 C# 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5034538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com