次の関数を検討してください。
static void Main(string[] args)
{
FileStream fs = new FileStream("e:\\temp.txt", FileMode.Open);
int size = (int)fs.Length;
byte[] data = new byte[size];
IAsyncResult result = fs.BeginRead(data, 0, size, new AsyncCallback(Callback), fs);
Console.ReadLine();
}
質問 1: BeginRead 行にブレークポイントを設定し、プログラムをデバッグ モードで実行すると、次のエラーが発生します。
MyApp.exe で、タイプ 'System.AccessViolationException' の未処理の例外が発生しました。
ただし、ブレークポイントを ReadLine 行に配置して同じことを行うと、エラーは発生しません。FileStream インスタンスを最後のパラメーターとして BeginRead 関数に渡すと問題が発生すると思いますが、そこで何が起こっているのかわかりません。
---UPDATE1:コールバックに「fs」を渡そうとする理由を尋ねるかもしれません。はい、メンバー変数として保持できますが、複数のファイルを非同期で読み取る場合はどうなりますか? そうすれば、ファイル ストリームの配列 (またはリスト) を保持することは不合理になります。
質問 2: 私の知る限り、IAsyncResult は次のように定義されています。
[ComVisible(true)]
public interface IAsyncResult
{
object AsyncState { get; }
WaitHandle AsyncWaitHandle { get; }
bool CompletedSynchronously { get; }
bool IsCompleted { get; }
}
ただし、コードをトレースすると、IAsyncResult に他のメンバーがいることに気付きました。
これはどのように可能ですか?IAsyncResult は明らかに ReadWriteTask クラス (この場合) によって実装されていますが、他のプロパティがどこから来たのかわかりません。
---更新 2: 次のコードを使用して同じことを模倣しようとしました:
public interface IMyInterface
{
int Prop1 { get; }
}
public class Impl : IMyInterface
{
public int Prop1 { get { return 101; } }
public int Prop2 { get { return 202; } }
}
public class MyClass
{
public IMyInterface GetMyInterface()
{
Impl impl = new Impl();
return impl;
}
}
メソッドを呼び出すには、次のように MyClass をインスタンス化し、GetMyInterface メソッドを呼び出します。
MyClass c = new MyClass();
IMyInterface my = c.GetMyInterface();
ただし、Quickwatch で my 変数を見ると、フラット化されていない結果が表示されますが、これはまったく問題ありません。ただし、これは IAsyncResult / ReadWriteTask の場合とは異なります。違いは何ですか?