ManualResetEvent.设置在c#中不会被解雇

本文关键字:设置 ManualResetEvent | 更新日期: 2023-09-27 18:04:32

我在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();
    }

}

现在,当我在uploadFile中使用evt.WaitOne()时,整个应用程序都在等待,没有请求发送到服务器,即代码永远不会达到getResponseCallBack,因此应用程序永远不会唤醒。然而,如果我不使用evt.WaitOne(),那么请求是成功的,但是我无法读取响应文本,因为它是在writeCallBack()函数中设置的,请求是异步的。我该怎么做才能解决这个问题?

<>之前我想不明白:1. 如果请求是多线程/异步的,那么为什么evt.WaitOne()使完整的应用程序等待而请求没有完成?2. 如果请求是单线程的,那么为什么postProcess()[删除event . waitone()]在试图访问responseStr[在getResponseCallBack()中设置]时没有得到正确的响应集呢?之前

[对不起,我不熟悉这个,我很困惑]。

谢谢。

对不起,我忘了说一件事,我使用silverlight

ManualResetEvent.设置在c#中不会被解雇

启动一个异步操作然后等待它完成是没有意义的。而不是异步request.BeginGetRequestStream(writeCallback, request);使用同步request.GetRequestStream(...)和消费它的结果。那么就不需要ManualResetEvent了。

这是我想出的问题的解决方案:

一些人建议使用HttpWebRequest.GetRequestStream并使呼叫同步。然而,silverlight似乎不允许这种情况发生。此外,还有许多与线程和并行处理相关的混淆。

主要问题是,我不能从我的回调函数访问UI thread,所以我使用dispatcher方法,因为它总是确保在UI线程中执行动作,我的目标得到了实现。

System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => { postProcess(); });