我有一个简单的程序,可以将文件并行复制到多个位置。我有一个弹出作为进度条的表单:
public partial class PleaseWait : Form
{
private static PleaseWait mInstance;
public static void Create()
{
var t = new System.Threading.Thread(() =>
{
mInstance = new PleaseWait();
mInstance.FormClosed += (s, e) => mInstance = null;
Application.Run(mInstance);
});
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.IsBackground = true;
t.Start();
}
public static void Destroy()
{
if (mInstance != null) mInstance.Invoke(new Action(() => mInstance.Close()));
}
public PleaseWait()
{
InitializeComponent();
}
public int t = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (t == 100)
{
t = 0;
}
else
{
t = t + 10;
progressBar1.Value = t;
}
}
}
我为每个副本线程调用Create
,然后在每个完成后销毁一次
10次中有9次会将它们关闭,但有时候我还剩下一次,所以我试过了
使用此代码
private void closewait()
{
foreach (Form f in Application.OpenForms)
{
if (f is file_copy.PleaseWait)
{
f.Dispose();
}
}
}
但是我遇到了一个交叉线程错误。如何确保副本完成后我还没有打开任何PleaseWait
表单。
答案 0 :(得分:0)
使用Dispose
在正确的主题上调用Control.Invoke
。
答案 1 :(得分:0)
你应该被称为PleaseWait表格的方法来关闭&自行处理。
并且PleaseWait表格应该使用一个标志是否结束计时器。
答案 2 :(得分:0)
可以引用来自多个线程的一个mInstance字段。
如果您只想显示“请等待”的一个副本,您应该创建参考计数器 mRef ++在创建表单上(当mRef> 0显示/创建表单时),mRef--在关闭表单上(当mRef == 0时,隐藏/关闭表单)。
如果您需要多个“Please Wait”,则应创建一组线程实例。
在这两种情况下,都不应使用线程共享静态字段。