コードベースに残っていて、ここ数年使用されているこの少しのレガシー コードがありますが、最近、そのメソッドStopImmediately()がそれをまったく停止しないことがわかりました。スレッドやバックグラウンド ワーカーをほとんど使ったことがないので、それがどのように機能するかについて頭も尻尾もわかりません。
経験豊富なスレッド フェラーの誰かが、この紛らわしい小さな獣がタスクを完了するのを止める方法を教えてくれるかどうか疑問に思っていました。以下は完全なクラスです(コードの量について申し訳ありません)
キャンセルする方法がわかりません..事前に助けてくれてありがとう..
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
namespace GPS2.BackgroundWorkerEx
{
public class QedBackgroundWorker
{
public QedBackgroundWorker() {}
Queue<object> Queue = new Queue<object>();
object lockingObject1 = new object();
private Thread currentThread;
public delegate void WorkerCompletedDelegate<K>(K result, Exception error);
public object Arguments { get; set; }
/// <summary>
/// doWork is a method with one argument
/// </summary>
/// <typeparam name="T">is the type of the input parameter</typeparam>
/// <typeparam name="K">is the type of the output result</typeparam>
/// <param name="inputArgument"></param>
/// <param name="doWork"></param>
/// <param name="workerCompleted"></param>
public void RunAsync<T,K>(Func<T, K> doWork, T inputArgument, WorkerCompletedDelegate<K> workerCompleted)
{
BackgroundWorker bw = GetBackgroundWorker<T,K>(doWork, workerCompleted);
Queue.Enqueue(new QueueItem(bw, inputArgument));
lock (lockingObject1)
{
if (Queue.Count == 1)
{
((QueueItem)this.Queue.Peek()).RunWorkerAsync();
//currentThread = System.Threading.Thread.CurrentThread;
}
}
}
/// <summary>
/// Use this method if you don't need to handle when the worker is completed
/// </summary>
/// <param name="doWork"></param>
/// <param name="inputArgument"></param>
public void RunAsync<T,K>(Func<T, K> doWork, T inputArgument)
{
RunAsync(doWork, inputArgument, null);
}
private BackgroundWorker GetBackgroundWorker<T, K>(Func<T, K> doWork, WorkerCompletedDelegate<K> workerCompleted)
{
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = true;
bw.DoWork += (sender, args) =>{
if (doWork != null)
{
args.Result = (K)doWork((T)args.Argument);
currentThread = System.Threading.Thread.CurrentThread;
}
};
bw.RunWorkerCompleted += (sender, args) =>{
if (workerCompleted != null)
{
workerCompleted((K)args.Result, args.Error);
}
Queue.Dequeue();
lock (lockingObject1)
{
if (Queue.Count > 0)
{
((QueueItem)this.Queue.Peek()).RunWorkerAsync();
}
}
};
return bw;
}
public void StopImmediately()
{
if (currentThread != null)
currentThread.Abort();
}
public bool IsBusy()
{
ThreadState state = currentThread.ThreadState;
bool res = true;
switch (state)
{
case ThreadState.Running:
res = true;
break;
default:
res = false;
break;
}
return res;
}
}
public class QueueItem{
public QueueItem(BackgroundWorker backgroundWorker, object argument)
{
this.BackgroundWorker = backgroundWorker;
this.Argument = argument;
}
public object Argument { get; private set; }
public BackgroundWorker BackgroundWorker { get; private set; }
public void RunWorkerAsync()
{
this.BackgroundWorker.RunWorkerAsync(this.Argument);
}
}
}