我有一个简单的程序,可以将文件并行复制到多个位置。我有一个作为进度条弹出的表单:
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
表格仍然打开。
使用 Control.Invoke
在正确的线程上调用Dispose
。
被称为PleaseWait表单的方法,以自行关闭和处置。
并且请等待表单应该使用标志来决定是否结束计时器。
这可能是由于引用了来自多个线程的一个 mInstance 字段。
如果只想显示"请稍候"的一个副本,则应创建参考计数器mRef++ 在创建表单上(当 mRef> 0 显示/创建表单时),mRef-- 在关闭表单上(当 mRef == 0 时,隐藏/关闭表单)。
如果需要多个"请稍候",则应创建线程实例数组。
在这两种情况下,您都不应使用线程共享静态字段。