0

Visual Web Express 2010に取り組んでいます。サーバーにファイルをアップロードし、呼び出し元の関数をブロックして、アップロードが完了したら解放しようとしています。ただし、メインスレッドのブロックが解除されることはありません。

public partial class MainPage : UserControl
{
    private FileStream fileStream;
    private static String responseStr = "";
    private static ManualResetEvent evt = new ManualResetEvent(false);
    public MainPage()
    {
        InitializeComponent();
        HtmlPage.RegisterScriptableObject("App", this);
    }

    public void sendPhoto()
    {
        uploadFile();
    }



    private void uploadFile()
    {
        uploadDataToServer(url);
        evt.WaitOne();
        postProcess();

    }

    public static void postProcess()
    {
        HtmlPage.Window.Invoke("postProcess2", responseStr);


    }

    void uploadDataToServer(String url)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.ContentType = "multipart/form-data; boundary=---------------------------" + _boundaryNo;
        request.Method = "POST";
        request.BeginGetRequestStream(writeCallback, request);
    }

    private void writeCallback(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
        MemoryStream memoryStream = new MemoryStream();
        fileStream.CopyTo(memoryStream);
        if (memoryStream != null)
        {
            memoryStream.Position = 0;
            byte[] img = memoryStream.ToArray();
            Stream postStream = request.EndGetRequestStream(asynchronousResult);
            postStream.Write(img, 0, img.Length);
            request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);

        }
    }

    private void GetResponseCallback(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
        Stream streamResponse = response.GetResponseStream();
        StreamReader streamRead = new StreamReader(streamResponse);
        string responseString = streamRead.ReadToEnd();
        streamRead.Close();
        streamResponse.Close();
        response.Close();
        responseStr = responseString;
        evt.Set();

    }


}

evt.WaitOne()これで、uploadFileで使用すると、アプリ全体が待機状態になり、サーバーにリクエストが送信されません。つまり、コードが到達getResponseCallBackしないため、アプリケーションがウェイクアップすることはありません。ただし、を使用しない場合、リクエストは成功しますが、関数に設定されており、リクエストが非同期であるevt.WaitOne()ため、レスポンステキストを読み取ることができません。writeCallBack()この問題を解決するにはどうすればよいですか?

私は理解できません:
1.リクエストがマルチスレッド/非同期の場合、なぜevt.WaitOne()がアプリ全体を待機させ、リクエストが完了しないのですか?
2.リクエストがシングルスレッドの場合、responseStr [getResponseCallBack()で設定]にアクセスしようとしたときにpostProcess()[evt.WaitOne()を削除]が適切なレスポンスセットを取得しないのはなぜですか。

[申し訳ありませんが、私はこれに不慣れで混乱しています]。

ありがとう。

申し訳ありませんが、私が使用していることを1つ言及するのを忘れましたsilverlight

4

2 に答える 2

0

私が見つけた問題の解決策は次のとおりです。

HttpWebRequest.GetRequestStream同期呼び出しを使用して作成することをお勧めする人もいます。ただし、Silverlight ではこれが許可されていないようです。さらに、スレッド化と並列処理に関連して多くの混乱がありました。

UI thread主な問題は、コールバック関数からにアクセスできなかったことでした。そのため、dispatcherメソッドを使用しました。アクションが常に UI スレッドで実行されるようにするため、私の目的は達成されました。以下はトリックを行いました。

System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => { postProcess(); });
于 2013-07-09T04:35:59.440 に答える
0

非同期操作を開始してから完了するのを待っても意味がありません。非同期の代わりにrequest.BeginGetRequestStream(writeCallback, request);同期request.GetRequestStream(...)を使用し、その結果を消費します。その場合、ManualResetEvent は必要ありません。

于 2013-03-19T07:56:18.643 に答える