BackgroundWorker取消异步真正的解决方案

        今天做了一个项目,其中使用到了BackgroundWorker,但是使用的时候遇到了一个问题。
问题:已经设置了 bgWorker.WorkerSupportsCancellation = true;
并且已经 bgWorker.CancelAsync(); 
但是在最后的最后访问 bgWorker.CancellationPending 值仍然为 false, 这就让人郁闷了。
后来终于摸索出来了解决方案:
1、首先必须设置支持异步取消 bgWorker.WorkerSupportsCancellation = true;
2、申请异步取消 bgWorker.CancelAsync(); 
3、在 bgWorker_DoWork( object sender, DoWorkEventArgs e ) 方法中,当任务结束后要进行判断并设置  e.Cancel = true;
如下:
 C# Code 
1
2
3
4
5
6
//开始异步时执行
private   void  bgWorker_DoWork( object  sender, DoWorkEventArgs e)
{
    excute();
    
if  (bgWorker.CancellationPending)
        e.Cancel = 
true ;
}
//然后在完成后获取e中的值
private  void bgWorker_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e)
{
     if (e.Cancelled ==  true)
        MessageBox.Show( "已取消!");
     else
        MessageBox.Show( "已完成!");
}
注意:两个参数e的类型是不一样的。
完整代码如下:
 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//取消操作xml
private   void  btnCancel_Click( object  sender, EventArgs e)
{
    bgWorker.CancelAsync();
}

string [] xmlFiles =  null ;
//打开文件
private   void  btnOpen_Click( object  sender, EventArgs e)
{
    OpenFileDialog open = 
new  OpenFileDialog();
    open.Multiselect = 
true ;
    open.Filter = 
"xml文件|*.xml|所有文件|*.*" ;
    
if  (open.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        
string [] files = open.FileNames;
        xmlFiles = files;
        
for  ( int  i =  0 ; i < files.Length; i++)
        {
            listBox1.Items.Add(files[i]);
            listBox1.SelectedIndex = listBox1.Items.Count - 
1 ;
        }
    }
}

//开始处理XML
private   void  btnImport_Click( object  sender, EventArgs e)
{
    
//如果正在运行,则不会进行任何操作
     if  (bgWorker.IsBusy)
        
return ;
    bgWorker.RunWorkerAsync();
}

//清空文件夹中所有文件
public   void  deleteAll( string  path)
{
    
string [] files = Directory.GetFiles(path);
    
for  ( int  i =  0 ; i < files.Length; i++)
    {
        File.Delete(files[i]);
    }
}
//开始异步时执行

private   void  bgWorker_DoWork( object  sender, DoWorkEventArgs e)
{
    excute();
    
if  (bgWorker.CancellationPending)
        e.Cancel = 
true ;
}
//收到汇报消息时执行

private   void  bgWorker_ProgressChanged( object  sender, ProgressChangedEventArgs e)
{
    
if (e.UserState.ToString().Contains( "未找到" ))
        MessageBox.Show(e.UserState.ToString(), 
"错误" , MessageBoxButtons.OK, MessageBoxIcon.Error);
    listBox1.Items.Add(e.UserState.ToString());
    listBox1.SelectedIndex = listBox1.Items.Count - 
1 ;
}
//异步完成时执行

private   void  bgWorker_RunWorkerCompleted( object  sender, RunWorkerCompletedEventArgs e)
{
    
if  (e.Cancelled ==  true )
        MessageBox.Show(
"已取消!" );
    
else
        MessageBox.Show( "已完成!" );
}
//窗体加载时执行

private   void  Form1_Load( object  sender, EventArgs e)
{
    //允许报告
    bgWorker.WorkerReportsProgress = 
true ;
    //允许异步取消
    bgWorker.WorkerSupportsCancellation = 
true ;


}

//处理xml
public   void  excute()
{
    
string  path = Directory.GetCurrentDirectory();
    
if  (File.Exists(path +  "\\name.txt" ))
    {
        Directory.CreateDirectory(path + 
"\\result" );
        deleteAll(path + 
"\\result" ); //清空
         for  ( int  k =  0 ; k < xmlFiles.Length; k++)
        {

            
//如果请求取消,跳出循环
             if  (bgWorker.CancellationPending)
                
break ;
            bgWorker.ReportProgress(
0 "正在处理"  + xmlFiles[k]);



            XmlDocument doc = 
new  XmlDocument();
            doc.Load(xmlFiles[k]);
            XmlNodeList list = doc.getElementsByTagName_r(
"ImagePath" );

            StreamReader sr = 
new  StreamReader(path +  "\\name.txt" , Encoding.Default);
            
string  line =  "" ;
            
int  nodeCount =  0 ;
            
int  nodeName =  0 ;
            List<</span>string> lines = new List<</span>string>();
            
while ((line = sr.ReadLine()) != null)
            {
                lines.Add(line);
            }
            
for (int i = 0; i < list.Count; i++)
            {
                nodeCount++;
                XmlNode node = list[i];
                
string text = node.InnerText;
                
int index = text.LastIndexOf("/");
                
int index1 = text.LastIndexOf(".");
                
string name = text.Substring(index + 1, index1 - index - 1);
                
for (int j = 0; j < lines.Count; j++)
                {
                    
//寻找是否有该节点对应的name
                    if (lines[j].Contains(name))
                    {
                        nodeName++;
                        
//寻找下一个节点是不是maskpath
                        if (node.NextSibling.Name != "MaskPath")
                        {
                            XmlNode afterNode = doc.createElement_x_x_x_x(
"MaskPath");
                            
string afterNodeText = text.Substring(0, index) + "/" + name + "_mask.tif";
                            afterNode.InnerText = afterNodeText;
                            XmlNode father = node.ParentNode;
                            father.InsertAfter(afterNode, node);

                            
//XmlNode father = node.ParentNode;
                            //father.RemoveChild(node.NextSibling);
                        }
                        
//找到以后后面的节点不再继续查找
                        break;
                    }

                }
            }
            doc.Save(path + 
"\\result\" + Path.GetFileName(xmlFiles[k]));
        }

    }
    
else
    {
        
string msg = "未找到" + path + "\\name.txt," + "请检查该路径文件!";
        bgWorker.ReportProgress(
0, msg);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIGIS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值