死锁 - Windows Phone 8 BeginGetResponse c#

时间:2015-04-15 19:41:40

标签: c# silverlight windows-phone-8 deadlock ui-thread

我的UI线程上运行了两个进程。但是,当我运行第一个,使用BeginGetStream功能时,它进入循环并等待它的执行并在你准备就绪时返回结果,但是在第二次运行中,通过BeginGetResponse功能,这个“死”在那里,程序做没有继续,并没有回报我想要的价值。在这些过程中使用IasynResult。

我试过了:

  • 转换为任务(Task.Run)

  • 为进程分配一个新线程(Thread x = new Thread())

  • 设置参数ConfigureAwait(ConfigureAwait(continueOnCapturedContext:false),ConfigureAwait(false));

  • 转换为asyncronos方法并应用“await”

  • 使用AutoResetEvent等待进程完成,不要继续。

  • 放置线程进入睡眠状态(Thread.Sleep)

  • 使用Thread.Start,Thread.Join

  • 等...

我基本上有三个函数(Function1,Function2和Function3)。 最初,我只使用Function2和function3,一切正常。 然后,按照文本顺序,我不希望UI线程锁定,它阻止,这次chamos我有三个函数,但是当我在Function2.Not中发出BeginGetResponse请求时,应用程序阻止了我。 (将整个项目置于异步中非常昂贵,因此这个选项将是最后一个。) 我不知道我能做什么...... :( 一些代码示例:


功能1:

public void Function1()
             {

                  {           
HttpWebRequest requestHttp = (HttpWebRequest)HttpWebRequest.CreateHttp(new Uri(serverUrl, UriKind.Absolute));

                        string RString = string.Format("rftoken=123456789");
                        AutoResetEvent handler = new AutoResetEvent(false);
                        IAsyncResult TestResult= null;
                        try
                        {
                            requestHttp.BeginGetRequestStream(
                                (IAsyncResult result) =>
                                {
                                    TestResult= result;
                                    handler.Set();
                                }, requestHttp );

                            handler.WaitOne();

                        }
                        catch (Exception) { }

                        return Function2(TestResult, RString );
                    }               
                }

-------- FUNCTION 2 ------------------------------------- -------------------------------------------------- -

private Example Function2(IAsyncResult TestResult2, string RString2)

    try
    {
        HttpWebRequest request = (HttpWebRequest)TestResult2.AsyncState;
        Stream strm = request.EndGetRequestStream(TestResult2);
        StreamWriter writer = new StreamWriter(strm);
        writer.Write(RString2);
        writer.Dispose();
    }
    catch
    {}

    AutoResetEvent handler = new AutoResetEvent(false);
    IAsyncResult Async= null;

    try
    {
        requestHttp.BeginGetRequestStream(
            (IAsyncResult result) =>
            {
                Async= result;
                handler.Set();
            }, requestHttp );

        handler.WaitOne();

    }
    catch (Exception) { }

    return Function3(Async);
} 
}

------------ FUNCTION 3 --------------------------------- -------------------------------------------------- ----

   private Example Function3 (IAsyncResult Async3)

{....}

......我不知道还有什么可以尝试......有人可以帮助我。

谢谢。

2 个答案:

答案 0 :(得分:0)

我认为您的UI线程阻塞是因为您在UI线程中的同步方法' Function1`中调用了handler.WaitOne();

我认为解决方法是将所有三个方法都作为异步函数,make方法也会将function1调用为异步方法。

我假设您在单击事件中调用Function1,并在获取结果后刷新UI。然后解决方案将是这样的:

用户界限线程

async void Click(object sender, RoutedEventArgs e)
{
        var result = await Function1();
}

功能1,功能2,功能3

async Task<Result> Function1()
{
    var resp = await requestHttp.BeginGetRequestStream();
    return Function2(resp);
}

async Task<Result> Function2(Response response)
{
    var resp2 = await xxxxx();
    return Function3(resp2);
}

async Task<Result> Function(Type2 response)
{
    await xxxxx();
    //calculation
    return Result;
}

答案 1 :(得分:0)

好的,所以我知道你使用的Silverlight框架只有异步方法。

你使用它们是错的,你的代码一定不能阻塞,你必须“让异步流”;)

void DownloadUrl()
{
    HttpWebRequest requestHttp = (HttpWebRequest)HttpWebRequest.CreateHttp(new Uri(serverUrl, UriKind.Absolute));

    requestHttp.BeginGetRequestStream(SendRequestContent, requestHttp);
}

void SendRequestContent(IAsyncResult Result)
{
    string RString = string.Format("rftoken=123456789");
    HttpWebRequest req = (HttpWebRequest)Result.AsyncState;
    var reqStream = req.EndGetRequestStream(Result);
    using(StreamWriter writer = new StreamWriter(reqStream))
        writer.Write(RString);

    //And here you have again GetRequestStream, I suppose it's wrong and you want ResponseStream, you cannot instantiate twice the request stream...

    req.BeginGetResponse(GetResponse, req);
}

void GetResponse(IAsyncResult Result)
{

    var req = (HttpWebRequest)Result.AsyncState;

    var response = (HttpWebResponse)req.EndGetResponse(Result);

    string content = null;

    using(StreamWriter sw = new StreamWriter(response.GetResponseStream())
        content = sw.ReadToEnd();

    //And now you have the HTTP response in the "content" string, you can now finally use it. Beware you are outside the UI thread, if you must interact with it remember to use Invoke()
}