我理解Thread.Abort()在我读过的关于这个主题的大量文章中是邪恶的,所以我目前正在扯掉我的中止,以便以更清洁的方式取代它; 并且在比较了stackoverflow上的人们的用户策略之后,然后在阅读MSDN上的" 如何:创建和终止线程(C#编程指南) "之后,两者都说明了一种非常相似的方法 - 即使用volatile bool方法检查策略,这很好,但我还有几个问题....
如果你没有一个简单的工作进程只是运行一个运算循环的代码,那么我的优势就在于此.比如说对我来说,我的进程是一个后台文件上传程序进程,我实际上是循环遍历每个文件,所以这是一些东西,并确保我可以while (!_shouldStop)在顶部添加我的每个循环迭代,但我有更多的业务流程它发生在它下一次循环迭代之前发生,我希望这个取消程序是快节奏的; 不要告诉我,我需要在整个工作人员功能中每隔4-5行循环播放这些内容吗?!
我真的希望有一个更好的方法,有人可以告诉我这是否实际上是正确的[并且只有?]做到这一点的方法,或者他们过去用来实现我所追求的目标的策略.
谢谢帮派.
进一步阅读:所有这些SO响应都假设工作线程将循环.这并不适合我.如果它是线性的,但是及时的背景操作怎么办?
以下是我们退出应用程序的方式:
Environment.Exit(0)Application.Exit()Form.Close()这三种方法之间的区别是什么?何时使用每种方法?
我创建了一个名为ProxyMonitor的Windows服务,我目前处于安装和卸载服务的阶段,就像我想要的那样.
所以我像这样执行应用程序:
C:\\Windows\\Vendor\\ProxyMonitor.exe /install
Run Code Online (Sandbox Code Playgroud)
非常自我解释,然后我得到services.msc并开始服务,但当我这样做时,我收到以下消息:
本地计算机上的代理监视器服务已启动,然后停止.如果没有工作要做,某些服务会自动停止,例如,性能日志和警报服务
我的代码看起来像这样:
public static Main(string[] Args)
{
if (System.Environment.UserInteractive)
{
/*
* Here I have my install logic
*/
}
else
{
ServiceBase.Run(new ProxyMonitor());
}
}
Run Code Online (Sandbox Code Playgroud)
然后在ProxyMonitor类中我有:
public ProxyMonitor()
{
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
ProxyEventLog.WriteEntry("ProxyMonitor Started");
running = true;
while (running)
{
//Execution Loop
}
}
Run Code Online (Sandbox Code Playgroud)
而onStop()我只是改变running变量false;
我需要做些什么来使服务保持活跃,因为我需要监控我需要跟踪变化等的网络.
更新:1
protected override void OnStart(string[] args)
{
base.OnStart(args);
ProxyEventLog.WriteEntry("ProxyMonitor Started");
Thread = new …Run Code Online (Sandbox Code Playgroud) 我不是想给打一个死 马,诚实.我已经阅读了有关线程查杀的所有建议,但请考虑代码.它执行以下操作:
StartThread方法)WAITFOR命令 - 这意味着它将一直坐在那里直到队列中有东西.这一切都在MonitorQueue方法中.杀死线程.我试过.Interrupt- 似乎什么也没做.然后我尝试了.Abort,永远不应该使用,但即使这样做也没有.
Thread thxMonitor = new Thread(MonitorQueue);
void StartThread() {
thxMonitor.Start();
}
void MonitorQueue(object obj) {
var conn = new SqlConnection(connString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandTimeout = 0; // forever and ever
cmd.CommandType = CommandType.Text;
cmd.CommandText = "WAITFOR (RECEIVE CONVERT(int, message_body) AS Message FROM SBQ)";
var dataTable = new DataTable();
var da = new SqlDataAdapter(command); …Run Code Online (Sandbox Code Playgroud)我有一个Windows服务使用Thread和SemaphoreSlim每60秒执行一些"工作".
class Daemon
{
private SemaphoreSlim _semaphore;
private Thread _thread;
public void Stop()
{
_semaphore.Release();
_thread.Join();
}
public void Start()
{
_semaphore = new SemaphoreSlim(0);
_thread = new Thread(DoWork);
_thread.Start();
}
private void DoWork()
{
while (true)
{
// Do some work here
// Wait for 60 seconds, or exit if the Semaphore is released
if (_semaphore.Wait(60 * 1000))
{
return;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想从中调用异步方法DoWork.为了使用await我必须添加async到的关键字DoWork:
private async void DoWork()
Run Code Online (Sandbox Code Playgroud)
我刚刚测试了一些我确信会失败的东西,但令我惊讶的是,它完美无瑕地工作,并向我自己证明我仍然对async-await工作的方式感到很困惑.
我创建了一个线程,将async void委托作为线程的主体传递.这是我的代码过度简化:
var thread = new Thread( async () => {
while( true ) {
await SomeLengthyTask();
...
}
});
thread.Start();
thread.Join();
Run Code Online (Sandbox Code Playgroud)
问题是,据我所知,当执行命中await关键字时,从方法中隐式返回,在这种情况下是循环线程的主体,而其余代码包含在回调延续中.
由于这个事实,我很确定线程会在await产生执行后立即终止,但事实并非如此!
有谁知道这个魔法是如何实际实现的?在async功能精简和async同步等待或者是有一些黑魔法将使它能够恢复已因为一次产生一个线程CLR正在做await?
我有一系列代码块花了太长时间.它失败时我不需要任何技巧.事实上,我想在这些块花费太长时间时抛出异常,并且只是通过我们的标准错误处理而失败.我宁愿不为每个块创建方法(这是我到目前为止看到的唯一建议),因为它需要重新编写代码库.
下面是我LIKE如果可能创造.
public void MyMethod( ... )
{
...
using (MyTimeoutObject mto = new MyTimeoutObject(new TimeSpan(0,0,30)))
{
// Everything in here must complete within the timespan
// or mto will throw an exception. When the using block
// disposes of mto, then the timer is disabled and
// disaster is averted.
}
...
}
Run Code Online (Sandbox Code Playgroud)
我使用Timer类创建了一个简单的对象.(注意那些喜欢复制/粘贴的人:这个代码不起作用!!)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
public class MyTimeoutObject : IDisposable
{
private Timer timer = null;
public MyTimeoutObject …Run Code Online (Sandbox Code Playgroud) 我需要终止一个冻结的线程,我将IsBackground设置为true但它仍然存活.线程的属性:
ThreadState = AbortRequested
IsBackground = true
当我检查冻结点时,我找到以下行:
resultDetect = Detect(input, ref output);
Run Code Online (Sandbox Code Playgroud)
该点是第三方代码(方法检测).线程仅在您看到时更新resultDetect.我需要中止该线程并重新启动一个新线程才能继续.否则,应用程序等待并且不执行任何操作 - 新结果需要 -
如何杀死不死的线程?
我可以用一些方法来杀死.NET 4.0 Task对象,就像我们可以使用旧的和危险的Thread.Abort()一样,在SO线程中讨论(双关语并保存小猫!)
肯尼
父母有几个子线程.
如果用户单击停止按钮,则应使用所有子线程终止父线程.
//calls a main thread
mainThread = new Thread(new ThreadStart(startWorking));
mainThread.Start();
////////////////////////////////////////////////
startWorking()
{
ManualResetEventInstance = new ManualResetEvent(false);
ThreadPool.SetMaxThreads(m_ThreadPoolLimit, m_ThreadPoolLimit);
for(int i = 0; i < list.count ; i++)
{
ThreadData obj_ThreadData = new ThreadData();
obj_ThreadData.name = list[i];
m_ThreadCount++;
//execute
WaitCallback obj_waitCallBack = new WaitCallback(startParsing);
ThreadPool.QueueUserWorkItem(obj_waitCallBack, obj_ThreadData);
}
ManualResetEventInstance.WaitOne();
}
Run Code Online (Sandbox Code Playgroud)
我想杀死mainThread.
重复:杀死一个帖子(C#)
如果我在3秒内没有收到回复,我需要一种方法来杀死这个线程.
完成此任务的最佳方法是什么?它不一定必须与thread/threadstart一起使用,这就是我到目前为止所使用的内容.
我想在后台运行一个长期运行的opeartion.要求是:
该操作应该与调用线程异步运行.
调用线程可以等待操作完成并获得其结果
超时后,应立即中止操作.
我本来会使用任务,但我知道没有机制可以杀死任务死冷.取消令牌不适合我,我只会因为未知原因而卡住任务 - (一个bug),这是一个故障安全机制.针说如果任务被卡住,请求取消没有用.BackgroundWorker也是如此.
有没有比在调用线程和后台线程之间使用共享对象更精细的东西?
c# ×11
.net ×5
winforms ×3
async-await ×2
.net-3.5 ×1
asynchronous ×1
kill ×1
parent ×1
vb.net ×1
windows ×1