Рабочий процесс BackgroundWorker
объект в основном требует, чтобы Вы обработали RunWorkerCompleted
событие и для нормального выполнения и для пользовательских вариантов использования отмены. Это то, почему свойство RunWorkerCompletedEventArgs. Отмененный существует. В основном выполнение этого правильно требует, чтобы Вы полагали, что Ваш метод Отмены асинхронный метод сам по себе.
Вот пример:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
namespace WindowsFormsApplication1
{
public class AsyncForm : Form
{
private Button _startButton;
private Label _statusLabel;
private Button _stopButton;
private MyWorker _worker;
public AsyncForm()
{
var layoutPanel = new TableLayoutPanel();
layoutPanel.Dock = DockStyle.Fill;
layoutPanel.ColumnStyles.Add(new ColumnStyle());
layoutPanel.ColumnStyles.Add(new ColumnStyle());
layoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
layoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
_statusLabel = new Label();
_statusLabel.Text = "Idle.";
layoutPanel.Controls.Add(_statusLabel, 0, 0);
_startButton = new Button();
_startButton.Text = "Start";
_startButton.Click += HandleStartButton;
layoutPanel.Controls.Add(_startButton, 0, 1);
_stopButton = new Button();
_stopButton.Enabled = false;
_stopButton.Text = "Stop";
_stopButton.Click += HandleStopButton;
layoutPanel.Controls.Add(_stopButton, 1, 1);
this.Controls.Add(layoutPanel);
}
private void HandleStartButton(object sender, EventArgs e)
{
_stopButton.Enabled = true;
_startButton.Enabled = false;
_worker = new MyWorker() { WorkerSupportsCancellation = true };
_worker.RunWorkerCompleted += HandleWorkerCompleted;
_worker.RunWorkerAsync();
_statusLabel.Text = "Running...";
}
private void HandleStopButton(object sender, EventArgs e)
{
_worker.CancelAsync();
_statusLabel.Text = "Cancelling...";
}
private void HandleWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
_statusLabel.Text = "Cancelled!";
}
else
{
_statusLabel.Text = "Completed.";
}
_stopButton.Enabled = false;
_startButton.Enabled = true;
}
}
public class MyWorker : BackgroundWorker
{
protected override void OnDoWork(DoWorkEventArgs e)
{
base.OnDoWork(e);
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(500);
if (this.CancellationPending)
{
e.Cancel = true;
e.Result = false;
return;
}
}
e.Result = true;
}
}
}
, Если бы Вы действительно действительно не хотите, чтобы Ваш метод вышел, я предложил бы поместить флаг как AutoResetEvent
на полученном BackgroundWorker
, затем переопределил бы OnRunWorkerCompleted
для установки флага. Это все еще довольно топорно хотя; я рекомендовал бы рассматривать событие отмены как асинхронный метод и сделал бы то, что оно в настоящее время делает в RunWorkerCompleted
обработчик.
Если Ваш хост позволяет Вам использовать exec()
, можно произвести его тот же путь как на CLI как это:
<?php
exec('php -i', $data);
var_dump($data);
знать, что это показало бы информации то же как на CLI, это ничего не знает о веб-сервере.