同时执行一个方法来编程窗口,并随时停止它

本文关键字:窗口 编程 方法 执行 一个 | 更新日期: 2023-09-27 18:28:20

我需要一个允许在后台执行方法并使窗口保持响应的功能,但我需要随时停止或挂起它。我知道线程在一定程度上回答了我的问题,但不幸的是,并没有办法阻止线程执行这样一个耗时的代码块。我曾想过过程沟通,但这是个好主意吗?或者可能有一种方法可以无条件地终止线程?

同时执行一个方法来编程窗口,并随时停止它

唯一的选择是,如果在代码执行的任何时候都可以停止代码是很重要的,并且当工作人员无法进行协作取消时,则需要有一个单独的进程。这是在您所描述的庄园中停止执行代码的最可靠的方法。使用线程无法可靠地完成此操作。

您似乎在寻找BackgroundWorker。

如果主线程要求它停止,您必须在第二个线程中进行检查,并在需要时进行检查。

简单(测试)示例:

public partial class Form1 : Form
{
    BackgroundWorker w = new BackgroundWorker();
    public Form1()
    {
        InitializeComponent();
        w.WorkerSupportsCancellation = true;
        w.DoWork += new DoWorkEventHandler(w_DoWork);
        w.RunWorkerAsync();
    }
    void w_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 10000000000; i++)
        {
            if (w.CancellationPending)
            {
                MessageBox.Show("Cancelled");
                break;
            }
            //Do things...
        }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        w.CancelAsync();
    }
}

编辑

如果你说的是HTTP请求,也许是:HttpWebRequest.Artrt?(尽管看到这个答案。)

如注释所述,thread.Abort()是一种选择,但不建议使用。相反,您应该使用thread.Interrupt(),其原因在这里有很好的详细说明。

不应该立即终止线程的原因是,这可能会导致锁定被设置,但永远不要取消设置,因为代码突然停止,没有路径。因此,如果它锁定了您需要重用的代码,就无法从上一次调用中解锁它。显然,您可以围绕这一点进行构建,但我假设您使用的是不是由您从头开始构建的阻塞代码。

你可以在一个单独的过程中完成,并以低得多的风险杀死这个过程,但随后来回传递数据,增加的混乱变得复杂起来。

这里有一个使用外部过程来完成这个卡盘的例子,并且能够杀死这个过程将降低风险。

public class Main
{
    public Main()
    {
        //In use
        DoCalculation calc = new DoCalculation();
        calc.StartCalculation(123, 188, ReceivedResults);
        //Cancel after 1sec
        Thread.Sleep(1000);
        calc.CancelProcess();
    }
    public void ReceivedResults(string result)
    {
        Console.WriteLine(result);
    }
}
public class DoCalculation
{
    private System.Diagnostics.Process process = new System.Diagnostics.Process();
    private Action<string> callbackEvent;
    public void StartCalculation(int var1, int var2, Action<string> CallbackMethod)
    {
        callbackEvent = CallbackMethod;
        string argument = "-v1 " + var1 + " -v2 " + var2;
        //this is going to run a separate process that you'll have to make and
        //you'll need to pass in the argument via command line args. 
        RunProcess("calcProc.exe", argument);
    }
    public void RunProcess(string FileName, string Arguments)
    {
        SecurityPermission SP = new SecurityPermission(SecurityPermissionFlag.Execution);
        SP.Assert();
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.FileName = FileName;
        process.StartInfo.Arguments = Arguments;
        process.StartInfo.WorkingDirectory = "";
        process.OutputDataReceived += ProcessCompleted;
        process.Start();
    }
    public void CancelProcess()
    {
        if (process != null)
            process.Kill();
    }
    private void ProcessCompleted(object sender, DataReceivedEventArgs e)
    {
        string result = e.Data;
        if (callbackEvent != null)
        {
            callbackEvent.Invoke(result);
        }
    }
}

你能给我们更多关于你到底在做什么的细节吗?也许有更好的选择来解决这个问题。