我使用异步拷贝的时候,想同时更新主线程创建的progressBar,代码如下:
class fileProgress
{
private void ReadFileCallback(IAsyncResult asynResult)
{ try
{
lock (fsoutput)
{
fsoutput.EndRead(asynResult);
} //把刚刚读入buffer的流写到目标文件中
if ((m_lOffsetpos + buffer.Length) < fsoutput.Length)
{
fsinput.BeginWrite(buffer, 0, buffer.Length, null, null);
}
//写最后一块,可能不满一个buffer,退出
else if(m_lOffsetpos >= fsoutput.Length)
{
fsinput.BeginWrite(buffer, 0, (int)(fsoutput.Length % buffer.Length), null, null);
//m_ProductManageSystem.textBoxFileInfo.Text = "文件复制完毕";
fsoutput.Close();
fsinput.Close();
return;
} //正常读,每次读一个buffer
if ((m_lOffsetpos + buffer.Length) < fsoutput.Length)
{
m_lOffsetpos += buffer.Length;
Application.DoEvents();
if (m_ProductManageSystem.m_pBar.InvokeRequired)
{
CallUpdateProgressValue cup = new CallUpdateProgressValue(UpdataPrgressValue);
this.BeginInvoke(null, null);
}
ProgressBar pBar = m_ProductManageSystem.m_pBar;
if (m_ProductManageSystem.m_pBar.InvokeRequired == true)
{
MethodInvoker m = new MethodInvoker(UpdataPrgressBar);
m.BeginInvoke(null, null);
} fsoutput.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadFileCallback), null);
} //读最后一段,可能不足一个buffer
else if (m_lOffsetpos + buffer.Length >= fsoutput.Length)
{
fsoutput.BeginRead(buffer, 0, (int)(fsoutput.Length - m_lOffsetpos), new AsyncCallback(ReadFileCallback), null);
m_lOffsetpos = fsoutput.Length;
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
} private void UpdataPrgressValue()
{
//读入一个buffer后,更新进度条显示
m_ProductManageSystem.m_pBar.Value = Convert.ToInt32(m_lOffsetpos * 100 / fsoutput.Length);
}
}每次调用的时候都会提示,“线程间调用无效,从不是创建控件“”的线程调用控件“的运行时错误,我在网上搜索过这个问题,比较疑惑,是不是BeginInvoke一定是contrl类才能调用的?我把我的fileProgress类改为继承control类,还会报错,“在创建窗口句柄之前,不能调用invoke或者BeginInvoke",请各位大侠帮帮忙,折磨好几天了,不知道怎么才行
class fileProgress
{
private void ReadFileCallback(IAsyncResult asynResult)
{ try
{
lock (fsoutput)
{
fsoutput.EndRead(asynResult);
} //把刚刚读入buffer的流写到目标文件中
if ((m_lOffsetpos + buffer.Length) < fsoutput.Length)
{
fsinput.BeginWrite(buffer, 0, buffer.Length, null, null);
}
//写最后一块,可能不满一个buffer,退出
else if(m_lOffsetpos >= fsoutput.Length)
{
fsinput.BeginWrite(buffer, 0, (int)(fsoutput.Length % buffer.Length), null, null);
//m_ProductManageSystem.textBoxFileInfo.Text = "文件复制完毕";
fsoutput.Close();
fsinput.Close();
return;
} //正常读,每次读一个buffer
if ((m_lOffsetpos + buffer.Length) < fsoutput.Length)
{
m_lOffsetpos += buffer.Length;
Application.DoEvents();
if (m_ProductManageSystem.m_pBar.InvokeRequired)
{
CallUpdateProgressValue cup = new CallUpdateProgressValue(UpdataPrgressValue);
this.BeginInvoke(null, null);
}
ProgressBar pBar = m_ProductManageSystem.m_pBar;
if (m_ProductManageSystem.m_pBar.InvokeRequired == true)
{
MethodInvoker m = new MethodInvoker(UpdataPrgressBar);
m.BeginInvoke(null, null);
} fsoutput.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadFileCallback), null);
} //读最后一段,可能不足一个buffer
else if (m_lOffsetpos + buffer.Length >= fsoutput.Length)
{
fsoutput.BeginRead(buffer, 0, (int)(fsoutput.Length - m_lOffsetpos), new AsyncCallback(ReadFileCallback), null);
m_lOffsetpos = fsoutput.Length;
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
} private void UpdataPrgressValue()
{
//读入一个buffer后,更新进度条显示
m_ProductManageSystem.m_pBar.Value = Convert.ToInt32(m_lOffsetpos * 100 / fsoutput.Length);
}
}每次调用的时候都会提示,“线程间调用无效,从不是创建控件“”的线程调用控件“的运行时错误,我在网上搜索过这个问题,比较疑惑,是不是BeginInvoke一定是contrl类才能调用的?我把我的fileProgress类改为继承control类,还会报错,“在创建窗口句柄之前,不能调用invoke或者BeginInvoke",请各位大侠帮帮忙,折磨好几天了,不知道怎么才行
可能你还没明白, 如果要源码, 网上很多都能搜到,关键字是 "c# 线程 操作 控件"
http://blog.csdn.net/jinjazz/archive/2008/05/06/2397136.aspx
VS.Net群-2号:4510861
VS.Net群-3号:22671516
VS.Net群-4号:23266396
VS.Net群-5号:13047396
VS.Net群-6号C++:57806388
VS.Net群-7号WinForm:62365220
VS.Net群-8号敏捷开发:62365516VS.Net技术群欢迎大家加入,发扬团队互助,长期潜水,将被提出!
请注明来自:csdn.
private void UpdataPrgressValue()
{
if (this.InvokeRequired)//这里最关键
{
this.Invoke=(new EventHandler(delegate { UpdataPrgressValue() }));
}
else
{
//读入一个buffer后,更新进度条显示
m_ProductManageSystem.m_pBar.Value = Convert.ToInt32(m_lOffsetpos * 100 / fsoutput.Length);
}
}
{
}
else{
m_ProductManageSystem.m_pBar.Value = Convert.ToInt32(m_lOffsetpos * 100 / fsoutput.Length);
}
{
}
在这个方法里面,用你那个窗口的.Invoke或者进度条控件的.Invoke方法,参数是一个delegate,委托一个方法来更新
进度条,这个方法会用UI线程去更新,就OK了.