【问题标题】:Deadlock - Windows Phone 8 BeginGetResponse c#死锁 - Windows Phone 8 BeginGetResponse c#
【发布时间】:2015-04-15 19:41:40
【问题描述】:

我的 UI 线程上有两个进程正在运行。但是,当我使用 BeginGetStream 功能运行第一次时,它进入循环并等待其执行并在您准备好时返回结果,但在第二次运行中,通过 BeginGetResponse 功能,这个“死”在那里并且程序确实不继续,也不返回我想要的值。在这些过程中使用 IasynResult。

我试过了:

  • 转换为任务(Task.Run)

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

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

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

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

  • 放置线程休眠(Thread.Sleep)

  • Thread.Start、Thread.Join的使用

  • 等等……

我基本上有三个函数(Function1、Function2 和 Function3)。 最初,我只使用 Function2 和 function3,一切正常。 然后,在下一个顺序中,我不希望 UI 线程锁定,它阻塞了,这一次我有三个函数,但是当我在 Function2 中请求 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 );
                    }               
                }

--------功能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);
} 
}

------------功能 3 --------------------------------- -------------------------------------------------- ----

   private Example Function3 (IAsyncResult Async3)

{....}

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

谢谢。

【问题讨论】:

  • 您不应手动创建 IAsyncResult,您必须通过 Begin'End' 函数传播生成的结果。另外,如果你正在做一个 handler.WaitOne(),你为什么要使用异步函数?你正在阻止那些线程......
  • 嗨,谢谢。因为我需要Function2的结果才能用正确的参数调用Function3,否则参数传递的值为null,而我想要的功能不在函数3中执行。
  • 不,你不明白我的意思,我的意思是,为什么在同步执行时使用异步方法?不要在函数中启动请求,而是阻止该函数并在其他函数中完成下载,只需在每个函数上同步执行该过程并隔离
  • 您好,我尝试将Function 1和Function加入同一个函数,问题依旧。我不明白为什么会这样。这会在程序运行 5 分钟后调用。我只是不明白为什么在我拨打第二个电话时将我锁定在 Function2 中。这是因为调用了 Funtion2 和 function3 来启动应用程序并且一切正常。第二次,当我调用Function1、Function2 和Funtion 3 时,卡在了Function2。我不明白这个问题。 ——谢谢
  • 正如我在回答中所说,您不能两次调用 BeginGetRequestStream,因此永远不会设置处理程序,因此应用程序会卡住

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


【解决方案1】:

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

我认为解决方案是将所有三个方法都设为异步函数,并让方法调用你的 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;
}

【讨论】:

  • 嗨,不,我没有在单击事件中调用 de Function1。在此之前调用的函数范围很广,但是问题是,当我在 Function2 中进行 BeginGetResponse 时。这会在程序运行 5 分钟后调用。我只是不明白为什么在我拨打第二个电话时将我锁定在 Function2 中。这是因为调用了 Funtion2 和 function3 来启动应用程序,一切正常。第二次,当我调用 Function1、Function2 和 Function 3 时,卡在了 Function2 中。我不明白这个问题。 ——谢谢
【解决方案2】:

好的,我知道您正在使用只有异步方法的 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()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多