C# 通知任务完成其工作

C# 通知任务完成其工作,c#,multithreading,C#,Multithreading,我在想一个简单的方法来完成任务。我提出了以下解决方案(用一个按钮将其粘贴到WinForms应用程序进行测试): 这是一个简单的取消场景,因此只有一个线程与UI线程并行运行 对于线程,是否有更简单(或更线程安全)的方法来实现此类通知 请考虑两个事实: 终止线程的唯一方法是中止它(这是因为我无法控制线程中正在执行的操作-第三方代码) 因此,我不能使用BackgroundWorker,因为它只提供了优雅的终止方式 是否有一种更简单(或更线程安全)的方式来实现线程的此类通知 是的,使用,让框架来管理

我在想一个简单的方法来完成任务。我提出了以下解决方案(用一个按钮将其粘贴到WinForms应用程序进行测试):

这是一个简单的取消场景,因此只有一个线程与UI线程并行运行

对于
线程
,是否有更简单(或更线程安全)的方法来实现此类通知

请考虑两个事实:

  • 终止线程的唯一方法是
    中止它(这是因为我无法控制线程中正在执行的操作-第三方代码)
  • 因此,我不能使用
    BackgroundWorker
    ,因为它只提供了优雅的终止方式
是否有一种更简单(或更线程安全)的方式来实现线程的此类通知

是的,使用,让框架来管理线程

Task.StartNew(() => {
   // do some stuff
}).ContinueWith((task) => {
   // do some stuff after I have finished doing some other stuff
});
或者,由于您使用的是WinForms,请使用并处理事件

我把你的kill误解为cancel——在.NET中没有可靠的方法可以真正杀死一个线程,甚至使用
Abort
或多或少是一场赌博,绝对不能保证线程会被杀死。而且,它会使线程和应用程序处于不可预测的状态,因此,如果您愿意冒这个风险,那么这取决于您


另一种方法是简单地让线程运行,但忽略结果,这取决于任务的大小。这可能没什么大不了的。

尽管您需要
中止
来终止线程,但您仍然可以使用TPL。您可以在任务中启动该线程,并等待它以及
取消令牌
。当任务在线程完成之前取消时,可以在线程上调用
Abort

看起来是这样的:

// In your class:
ManualResetEvent threadFinished = new ManualResetEvent(false);

// In your calling function (button1_Click):
Task.Run( () => {

    ThreadStart threadStart = new StreadStart(DoWork);
    threadStart += () => { threadFinished.Set(); }
    Thread thread = new Thread(threadStart);
    threadFinished.Reset();

    thread.Start();
    WaitHandle waitCancel = cancellationToken.WaitHandle;
    int waited = WaitHandle.WaitAny( new WaitHandle[]{ waitCancel, threadFinished } );

    if (waited == 0 && cancellationToken.IsCancellationRequested)
        thread.Abort();
    else
        thread.Join()

});

这不是提出这个问题的好地方吗?我重新表述了这个问题。你使用的是哪个.NET框架?您是否明确需要使用线程?我如何才能终止此类任务?@Spook您不需要,一旦完成,线程将自动放回线程池,并可用于其他资源(或者,如果框架认为合适,它将处理清理)。我的要求是,用户将能够终止该任务(这是一种情况,第二种情况是以一种应对这种情况的方式优雅地结束)。线程实际上运行一个不可中断的脚本解释器,如果脚本进入无休止的循环,我必须给用户一个终止脚本的选项。这就是为什么我使用线程而不是BackgroundWorker。@天哪,你说的不是杀死一个任务,而是取消一个任务(两件完全不同的事情)和都支持这一点。请阅读我的整个问题,包括底部的两个注释。我不能取消任务,我必须终止任务,因为无法优雅地停止它。
// In your class:
ManualResetEvent threadFinished = new ManualResetEvent(false);

// In your calling function (button1_Click):
Task.Run( () => {

    ThreadStart threadStart = new StreadStart(DoWork);
    threadStart += () => { threadFinished.Set(); }
    Thread thread = new Thread(threadStart);
    threadFinished.Reset();

    thread.Start();
    WaitHandle waitCancel = cancellationToken.WaitHandle;
    int waited = WaitHandle.WaitAny( new WaitHandle[]{ waitCancel, threadFinished } );

    if (waited == 0 && cancellationToken.IsCancellationRequested)
        thread.Abort();
    else
        thread.Join()

});