4

ImageWCF サービスから取得しようとしています。

クライアントにOperationContractを返す関数がありますImageが、クライアントから呼び出すと、次の例外が発生します。

ソケット接続が中止されました。これは、メッセージの処理中にエラーが発生したか、リモート ホストが受信タイムアウトを超過したか、基になるネットワーク リソースの問題が原因である可能性があります。ローカル ソケットのタイムアウトは「00:00:59.9619978」でした。

クライアント:

private void btnNew_Click(object sender, EventArgs e)
{
    picBox.Picture = client.GetScreenShot();
}

Service.cs:

public Image GetScreenShot()
{
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    using (Bitmap bmp = new Bitmap(bounds.Width,bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
        }
        using (MemoryStream ms = new MemoryStream())
        {
            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            return Image.FromStream(ms);
        }
    }
}

IScreenShotインターフェース:

[ServiceContract]
public interface IScreenShot
{
    [OperationContract]
    System.Drawing.Image GetScreenShot();
}

では、なぜこれが起こっているのでしょうか。どうすれば修正できますか?

4

3 に答える 3

7

私はそれを理解しました。

  • 最初の使用TransferMode.StreamedまたはStreamedResponse(必要に応じて)。
  • Stream.Postion = 0ストリームを返し、最初からストリームを読み始めるように設定することを忘れないでください。

サービス内:

public Stream GetStream()
{
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    using (Bitmap bmp = new Bitmap(bounds.Width, bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
        }
        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        ms.Position = 0;  // This is very important
        return ms;
    }
}

インターフェース:

[ServiceContract]
public interface IScreenShot
{
    [OperationContract]
    Stream GetStream();
}

クライアント側:

public partial class ScreenImage: Form
{
    ScreenShotClient client;
    public ScreenImage(string baseAddress)
    {
        InitializeComponent();
        NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
        binding.TransferMode = TransferMode.StreamedResponse;
        binding.MaxReceivedMessageSize = 1024 * 1024 * 2;
        client = new ScreenShotClient(binding, new EndpointAddress(baseAddress));
    }

    private void btnNew_Click(object sender, EventArgs e)
    {
        picBox.Image = Image.FromStream(client.GetStream());
    }
}
于 2012-05-15T20:50:24.787 に答える
3

Stream を使用して、大きなデータ/画像を返すことができます。

MSDN のサンプル例 (画像をストリームとして返す)

于 2012-05-14T13:45:25.523 に答える
1

シリアライズ可能なものを定義する必要があります。ただし、デフォルトSystem.Drawing.Imageでは (を使用して) WCF のコンテキストではありません。DataContractSerializerこれは、生のバイトを配列として返すこと、文字列 (base64、JSON) へのシリアル化、またはシリアル化DataContract可能でデータを一緒に運ぶことができる を実装することまで、さまざまです。

他の人が言ったように、WCF はストリーミングをサポートしていますが、それはここでの問題の核心ではありません。これを実行したいデータのサイズによっては、(明らかなトップレベル ビューから) バイトをストリーミングするため、そうすることで問題自体が軽減されます。

この回答を見て、障害情報だけでなく完全なスタックトレースなど、実際の例外の詳細を取得することもできます。

于 2012-05-14T13:39:33.697 に答える