C# 在操作中间立即取消后台工作人员

C# 在操作中间立即取消后台工作人员,c#,winforms,backgroundworker,C#,Winforms,Backgroundworker,我试图了解我能和背景工作者做什么,不能做什么。我已经看过很多关于这个的帖子,但是它似乎都涉及到一些循环操作,你在一个循环中取消了一个操作。我想知道我是否可以在没有循环的情况下取消后台工作程序上的某些操作。 我玩的是以下简单的表单: 其中包含以下代码: string[,] TestData = new string[300000, 100]; List<string> TestDataList; private static Random random = new Random();

我试图了解我能和背景工作者做什么,不能做什么。我已经看过很多关于这个的帖子,但是它似乎都涉及到一些循环操作,你在一个循环中取消了一个操作。我想知道我是否可以在没有循环的情况下取消后台工作程序上的某些操作。
我玩的是以下简单的表单:

其中包含以下代码:

string[,] TestData = new string[300000, 100];
List<string> TestDataList;
private static Random random = new Random();

public Form1()
{
    InitializeComponent();
    // Loading up some fake data
    for (int i = 0; i < 300000; i++)
    {
        for (int j = 0; j < 100; j++)
        {
            this.TestData[i, j] = RandomString(10) + j.ToString();
        }
    }
}
public static string RandomString(int length)
{
    const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    return new string(Enumerable.Repeat(chars, length)
      .Select(s => s[random.Next(s.Length)]).ToArray());
}
我还有:

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    this.TestDataList = this.TestData.Cast<string>()
    .Select((s, i) => new { GroupIndex = i / 100, Item = s.Trim().ToLower() })
    .GroupBy(g => g.GroupIndex)
    .Select(g => string.Join(",", g.Select(x => x.Item))).ToList();

}

private void bw_Complete(object sender, RunWorkerCompletedEventArgs e)
{
    this.showWorkingLabel.Text = "Work done";
}

private void btnCancel_Click(object sender, EventArgs e)
{
    // I want to cancel the work with this button


    // Then show
    this.showWorkingLabel.Text = "Work Cancelled";
}
  • 我是否可以在后台工作进行时更新标签
    showWorkingLabel
    ,使其连续显示
    “,”,“…”
    ,然后像进度条一样返回到
    ,以指示工作仍在进行
  • 根据:

    创建辅助进程时,可以通过设置

    backgroundWorker.WorkerSupportsCancellation = true;
    
    您可以通过在BackgroundWorker上调用
    CancelAsync()
    来请求取消

    然后,BackgroundWorker应定期检查
    BackgroundWorker.CancellationPending
    属性,如果设置为
    true
    ,则应取消其操作。正如鲁福爵士在评论中指出的那样,不要忘记在
    DoWork
    委托中设置
    DoWorkEventArgs.Cancel
    true

    我链接的MSDN页面中有其他在真实代码中使用的示例。

    根据:

    创建辅助进程时,可以通过设置

    backgroundWorker.WorkerSupportsCancellation = true;
    
    您可以通过在BackgroundWorker上调用
    CancelAsync()
    来请求取消

    然后,BackgroundWorker应定期检查
    BackgroundWorker.CancellationPending
    属性,如果设置为
    true
    ,则应取消其操作。正如鲁福爵士在评论中指出的那样,不要忘记在
    DoWork
    委托中设置
    DoWorkEventArgs.Cancel
    true


    我链接的MSDN页面中有其他在真实代码中使用的示例。

    您首先需要支持取消

    bw.WorkerSupportsCancellation = true;
    
    然后,您需要在表单级别共享取消令牌

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken cancellationToken;
    
    在您的工作中,您需要取消:

    cancellationToken.ThrowIfCancellationRequested();
    
    或者,即使对于挂起的取消,也可以与后台工作人员优雅地处理它:
    BackgroundWorker.CancellationPending

    在取消按钮中,您可以按如下方式调用取消:

    cts.Cancel();
    
    使用您的代码,它将类似于以下指示,您应该处理优雅的取消:

        string[,] TestData = new string[30000, 100];
        List<string> TestDataList;
        private static Random random = new Random();
        CancellationTokenSource cts = new CancellationTokenSource();
        CancellationToken cancellationToken;
    
        private void BtnStart_Click(object sender, EventArgs e)
        {
            try
            {
                this.showWorkingLabel.Text = "Work start";
                System.Threading.SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
                BackgroundWorker bw = new BackgroundWorker();
                bw.WorkerSupportsCancellation = true;
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    
                cancellationToken = cts.Token;
                cancellationToken.Register(bw.CancelAsync);
    
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_Complete);
                bw.RunWorkerAsync();
    
            }
            catch (Exception ex)
            {
                MessageBox.Show("Something went wrong.\nError:" + ex.Message);
            }
        }
    
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            cancellationToken.ThrowIfCancellationRequested();
            this.TestDataList = this.TestData
                .Cast<string>()
                .Select((s, i) => new { GroupIndex = i / 100, Item = s.Trim().ToLower() })
                .GroupBy(g => g.GroupIndex)
                .Select(g =>
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    return string.Join(",", g.Select(x => x.Item));
                })
                .ToList();
        }
    
        private void btnCancel_Click(object sender, EventArgs e)
        {
            cts.Cancel();
    
            this.showWorkingLabel.Text = "Work Cancelled";
        }
    
    string[,]TestData=新字符串[30000100];
    列表TestDataList;
    私有静态随机=新随机();
    CancellationTokenSource cts=新的CancellationTokenSource();
    取消令牌取消令牌;
    私有void BtnStart_单击(对象发送方,事件参数e)
    {
    尝试
    {
    this.showWorkingLabel.Text=“工作开始”;
    System.Threading.SynchronizationContext.SetSynchronizationContext(新WindowsFormsSynchronizationContext());
    BackgroundWorker bw=新的BackgroundWorker();
    bw.workersupport扫描单元=真;
    bw.DoWork+=新DoWorkEventHandler(bw_DoWork);
    cancellationToken=cts.Token;
    cancellationToken.Register(bw.CancelAsync);
    bw.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(bw_Complete);
    RunWorkerAsync();
    }
    捕获(例外情况除外)
    {
    MessageBox.Show(“出现问题。\n错误:+ex.Message”);
    }
    }
    私有void bw_DoWork(对象发送方,DoWorkEventArgs e)
    {
    cancellationToken.ThrowIfCancellationRequested();
    this.TestDataList=this.TestData
    .Cast()
    .Select((s,i)=>new{GroupIndex=i/100,Item=s.Trim().ToLower()})
    .GroupBy(g=>g.GroupIndex)
    .选择(g=>
    {
    cancellationToken.ThrowIfCancellationRequested();
    返回string.Join(“,”,g.Select(x=>x.Item));
    })
    .ToList();
    }
    私有void btnCancel\u单击(对象发送者,事件参数e)
    {
    cts.Cancel();
    this.showWorkingLabel.Text=“工作已取消”;
    }
    
    您首先需要支持取消

    bw.WorkerSupportsCancellation = true;
    
    然后,您需要在表单级别共享取消令牌

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken cancellationToken;
    
    在您的工作中,您需要取消:

    cancellationToken.ThrowIfCancellationRequested();
    
    或者,即使对于挂起的取消,也可以与后台工作人员优雅地处理它:
    BackgroundWorker.CancellationPending

    在取消按钮中,您可以按如下方式调用取消:

    cts.Cancel();
    
    使用您的代码,它将类似于以下指示,您应该处理优雅的取消:

        string[,] TestData = new string[30000, 100];
        List<string> TestDataList;
        private static Random random = new Random();
        CancellationTokenSource cts = new CancellationTokenSource();
        CancellationToken cancellationToken;
    
        private void BtnStart_Click(object sender, EventArgs e)
        {
            try
            {
                this.showWorkingLabel.Text = "Work start";
                System.Threading.SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
                BackgroundWorker bw = new BackgroundWorker();
                bw.WorkerSupportsCancellation = true;
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    
                cancellationToken = cts.Token;
                cancellationToken.Register(bw.CancelAsync);
    
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_Complete);
                bw.RunWorkerAsync();
    
            }
            catch (Exception ex)
            {
                MessageBox.Show("Something went wrong.\nError:" + ex.Message);
            }
        }
    
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            cancellationToken.ThrowIfCancellationRequested();
            this.TestDataList = this.TestData
                .Cast<string>()
                .Select((s, i) => new { GroupIndex = i / 100, Item = s.Trim().ToLower() })
                .GroupBy(g => g.GroupIndex)
                .Select(g =>
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    return string.Join(",", g.Select(x => x.Item));
                })
                .ToList();
        }
    
        private void btnCancel_Click(object sender, EventArgs e)
        {
            cts.Cancel();
    
            this.showWorkingLabel.Text = "Work Cancelled";
        }
    
    string[,]TestData=新字符串[30000100];
    列表TestDataList;
    私有静态随机=新随机();
    CancellationTokenSource cts=新的CancellationTokenSource();
    取消令牌取消令牌;
    私有void BtnStart_单击(对象发送方,事件参数e)
    {
    尝试
    {
    this.showWorkingLabel.Text=“工作开始”;
    System.Threading.SynchronizationContext.SetSynchronizationContext(新WindowsFormsSynchronizationContext());
    BackgroundWorker bw=新的BackgroundWorker();
    bw.workersupport扫描单元=真;
    bw.DoWork+=新DoWorkEventHandler(bw_DoWork);
    cancellationToken=cts.Token;
    cancellationToken.Register(bw.CancelAsync);
    bw.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(bw_Complete);
    RunWorkerAsync();
    }
    捕获(例外情况除外)
    {
    MessageBox.Show(“出现问题。\n错误:+ex.Message”);
    }
    }
    私有void bw_DoWork(对象发送方,DoWorkEventArgs e)
    {
    cancellationToken.ThrowIfCancellationRequested();
    this.TestDataList=this.TestData