Останавливать поток нужно не убиванием его, а остановкой, желательно - изнутри. А чтобы это можно было сделать нужно передать внутрь токен останова. Сам останов ничего не делает, но он используется внутри тела потока для отмены или аварийного завершения. Этот токен передастся в Worker, в котором нужно будет проверять наличие останова с помощью
cancellationToken.IsCancellationRequested
. Если в воркере используется цикл, то проверять можно в каждой итерации.
var formWait = new FormWait(cancellationToken =>
{
foreach(var item in _items)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
item.DoWork();
}
});
wait.Stop = delegate ()
{
var source = _tokenSource;
if (source != null)
{
source.Cancel();
source.Dispose();
_tokenSource = null;
}
};
myThread.Start();
В форме:
public Action<CancellationToken> Worker { get; } // добавляем ссылку на токен останова
public Action Stop { get; set; }
private CancellationTokenSource _tokenSource;
public FormWait(Action<CancellationToken> worker)
{
InitializeComponent();
if (worker == null)
throw new ArgumentNullException();
Worker = worker;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_tokenSource?.Dispose();
_tokenSource = new CancellationTokenSource();
var cancellationToken = = _tokenSource.Token;
Task.Factory.StartNew(() => Worker(cancellationToken ))
.ContinueWith(t => { this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());
}
private void button1_Click(object sender, EventArgs e)
{
Console.WriteLine("Stop");
Stop();
}
Возможно, хорошо сделать таск с возвращаемым результатом, например
public Func<CancellationToken, bool> Worker { get; }
Task.Factory.StartNew<bool>(() => Worker(cancellationToken))
.ContinueWith(t => { if (t.Result) this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());