none
FileStream.BeginRead RRS feed

  • 問題

  • 之前使用同步呼叫非同步時會發生這個問題,雖然目前以其他方法解決
    IAsyncResult 物件並非來自此型別上對應的 async 方法,或者 EndRead 已經以相同的 IAsyncResult 呼叫多次。

    今天注意到this.FileReadStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(zEndReadCallBack),null); object 其說明是使用者所提供的物件,可從其他要求中區分出這個特定非同步讀取的要求
    看字面上的意思這個asyncResult.object是可以解決上面那個問題嗎,讓每一個endreadcallback不會呼叫到同樣的IAsyncResult,之後看了msdn簡潔的說明…,好像是己建立好filestearm(xxx,xxx),在endreadcallback中宣告filestearm=object的樣子,不過還是一知半解,有人有使用過的經驗嗎,麻煩可以解說一下 object和endreadcallback裡該如何使用
     private void zEndReadCallBack(IAsyncResult ar)  
            {  
                int ReadedLength;  
                // Lock FileStream   
                lock (this.FileReadStream)  
                {  
                    ReadedLength = this.FileReadStream.EndRead(ar);   // When stream endread, get readed length   
     
                }  
                // Write to disk   
                if (this.FileWriteStream.CanWrite == true)  
                {  
                    this.FileWriteStream.Write(buffer, 0, buffer.Length);  
                }  
     
                Position += ReadedLength;  
                if (Position >= TotalSize) // Read over.   
                {  
                    FileReadStream.Close();  
                    FileWriteStream.Close();  
                    this.Moved(this, new MoveEventArgs(zSourcePath, zTargetPath, zFunName));  
                    return;  
                }  
                else  
                {  
                    lock (this.FileReadStream)  
                    {  
                        int leftSize = TotalSize - Position;  
                        if (leftSize > BUFFER_SIZE)  
                        {  
                            buffer = new byte[BUFFER_SIZE];  
                            this.FileReadStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(zEndReadCallBack),null);  
                        }  
                        else  
                        {  
                            buffer = new byte[leftSize];  
                            this.FileReadStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(zEndReadCallBack),null);  
                        }  
                    }  
                }  
            } 




    2009年3月19日 上午 03:24

解答

  • 在大多數的非同步回呼的方法中,都有state object,用來傳遞一些參數
    這個state object可以依你的需求去自訂
    比方說,你可以自訂一個類別,包自己想包的東西進去
    這是一個你自訂的Class
     public class myState
        {
            string strUsername;
            string strPassword;
        }

    你在這個之前可以New 一個自訂Class的Instance,我們就稱之為 objState好了
    並且指派值給這個objState
    所以這個
    this.FileReadStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(zEndReadCallBack),null);
    就可以改成
    this.FileReadStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(zEndReadCallBack),objState);
    那你的 zEndReadCallback(IAsyncResult asyncResult)程序中
    就可以用
    myState tempState = (myState)asyncResult.AsyncState;
    去取得傳進來的資料
    此時
    tempState.strUsername 就是會等於剛剛傳進來的 objState.strUsername


    • 已標示為解答 ericstone 2009年3月25日 上午 02:41
    2009年3月19日 上午 05:42
    版主