进程问题(backgroundworker)请帮忙看下

zf19811031 2017-09-14 03:17:41
A页面在点击按钮后有一段较长的处理,所以在处理时显示一个小页面(loading)显示“处理中”。
目前做法是在A页面中引入BackgroundWorker。
把相关处理放入DOWORK绑定的函数中。
现象,dowork和CompleteWork处理结束,A页面一直在显示没有应答,请大家帮忙看下是不是有什么操作漏了,谢谢!
绑定部分
CheckForIllegalCrossThreadCalls = false;
bkWorker.WorkerReportsProgress = true;
bkWorker.WorkerSupportsCancellation = true;
bkWorker.DoWork += new DoWorkEventHandler(DoWork);
bkWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompleteWork);

后台处理呼出
...
...
...
public loading RunningWindow = new loading();
bkWorker.RunWorkerAsync();
RunningWindow.ShowDialog();

...
...

private void DoWork(object sender, DoWorkEventArgs e)
{
...
}

private void CompleteWork(object sender, RunWorkerCompletedEventArgs e)
{


MessageBox.Show("处理结束", "处理结束", MessageBoxButtons.OK, MessageBoxIcon.Information);

bkWorker.CancelAsync();

RunningWindow.Dispose();

RunningWindow.Close();


}
...全文
156 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
为了判断关闭模态对话框的操作是否发生在主线程,可以打印线程 Id。
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Debug.Print("主线程 " + Thread.CurrentThread.ManagedThreadId);
        var f = new Form2();
        this.backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
        this.backgroundWorker1.RunWorkerCompleted += (s, arg) =>
        {
            Debug.Print("RunWorkerCompleted 事件发送在主线程 " + Thread.CurrentThread.ManagedThreadId);
            f.Close();
        };
        this.backgroundWorker1.RunWorkerAsync();
        f.ShowDialog();
        MessageBox.Show("Form2关闭啦");
    }

    private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Debug.Print("子线程 " + Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(3000);
    }
  • 打赏
  • 举报
回复
另外,提醒你一点,永远不要将 CheckForIllegalCrossThreadCalls 设置为 false。
  • 打赏
  • 举报
回复
我给你写一个例子。假设 Form1 有一个 backgroundWorker 控件实例,这个窗口以模态对话框方式打开 form2,那么用户交互操作焦点是不能回到 Form1 上的。但是主线程仍然是可以回到 Form1的。这说明了 ShowDialog 的机制,也就是说它只是针对交互操作焦点问题,而并不阻塞主线程操作! 代码如下:
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        var f = new Form2();
        this.backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
        this.backgroundWorker1.RunWorkerCompleted += (s, arg) => f.Close();
        this.backgroundWorker1.RunWorkerAsync();
        f.ShowDialog();
        MessageBox.Show("Form2关闭啦");
    }

    private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(3000);
    }
你可以看到,3秒钟之后 Form2 实例自动关闭了,从而执行了 MessageBox.Show 语句。可见 ShowDiaplog 是只阻塞用户交互,并不阻塞主线程。
小赛不哭 2017-09-14
  • 打赏
  • 举报
回复
异常处理机制有问题
exception92 2017-09-14
  • 打赏
  • 举报
回复
dowork和CompleteWork处理结束 -》处理结束并不代表“成功”处理,也有可能异常。 但是你在CompleteWork方法中调用 bkWorker.CancelAsync(); 取消异步实在理解不了。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧