今天無聊自己玩了一下檔案複製
用了FileStream來自行copy
今天無聊自己玩了一下檔案複製
用了FileStream來自行copy
FileStream _reader = new FileStream(filePath, FileMode.Open);
FileStream _writer = new FileStream(DescPath, FileMode.OpenOrCreate, FileAccess.Write);
int _readerCount = 0;
byte[] data;
do
{
data = new byte[tnsLen];
_readerCount = _reader.Read(data, 0, tnsLen);
pro += _readerCount;
_writer.Write(data, 0, _readerCount);
label1.Text = pro.ToString();
} while (_readerCount > 0);
F5給他按下去後要移動程式就送我這個畫面
然後就要乖乖的等待程式copy完才可以做其他的事情
要解決這種窘境在.NET我想可能用非同步處理會蠻適合的
Action moveFileDelegate = new Action(MoveFile);
moveFileDelegate.BeginInvoke(new AsyncCallback(delegate(IAsyncResult iar)
{
MessageBox.Show("OK");
}), null);
唉阿,原來另外開一條執行緒在後面並行作業會出現這種錯誤
想想也沒錯
多條執行緒共用同一個control到底的確是不合理
後來摸索了一陣子發現可以由表單本身來控制
把更新label的程式放進delegate後讓from本身來invoke就可以解決此問題
不過有時可能不需要不斷的更新control
只需要在完成的時候更新狀態即可
這時可以把MoveFile改為回傳int並呼叫EndInvoke取得結果即可
類似這樣
moveFileDelegate moveDelegate = new moveFileDelegate(this.MoveFile);
moveDelegate.BeginInvoke(delegate(IAsyncResult iar)
{
AsyncResult ar = (AsyncResult)iar;
moveFileDelegate mDelegate = (moveFileDelegate)ar.AsyncDelegate;
int _result = mDelegate.EndInvoke(iar);
this.Invoke(new UpdateDelegate(UpdateLabel), _result.ToString());
}, null);
或是直接將此delegate當作BeginInvoke的最後一個參數傳進AsyncCallback也可以
moveFileDelegate moveDelegate = new moveFileDelegate(this.MoveFile);
moveDelegate.BeginInvoke(delegate(IAsyncResult iar)
{
moveFileDelegate mDelegate = (moveFileDelegate)iar.AsyncState;
int _result = mDelegate.EndInvoke(iar);
this.Invoke(new UpdateDelegate(UpdateLabel), _result.ToString());
}, moveDelegate);
這邊可以發現BeginInvoke的最後一個參數在AsyncCallback中可以由傳入的IAsyncResult的AsyncState取得
所以我也可以改寫為
moveFileDelegate moveDelegate = new moveFileDelegate(this.MoveFile);
moveDelegate.BeginInvoke(delegate(IAsyncResult iar)
{
AsyncResult ar = (AsyncResult)iar;
UpdateDelegate mDelegate = (UpdateDelegate)iar.AsyncState;
this.Invoke(mDelegate, ((moveFileDelegate)ar.AsyncDelegate).EndInvoke(iar).ToString());
}, new UpdateDelegate(UpdateLabel));
經過這次嘗試
相信下次再處理非同步作業時能更得心應手