1

现在我使用并行方法来检查 200 状态代码的 url,但这是一种缓慢的方法。现在我正在尝试将我的代码移动到等待/异步方法,但它不起作用

        private async void button1_Click(object sender, EventArgs e)
        {
            DateTime start = DateTime.Now;

            var timerPostingSpeed = new Timer(state =>
            {
                TimeSpan elapsed = DateTime.Now - start;
                string postingSpeed = string.Format("{0:0}",
                                                   finishedUrls * 60 / (int)elapsed.TotalSeconds);
                UpdatingLabel(label1, postingSpeed);
            }, null, 5000, 10000);


            IEnumerable<string> urls = File.ReadLines("urls.txt");

            var engine = Python.CreateEngine();

            var scriptSource =
                   engine.CreateScriptSourceFromString(@"
                        if Open(__URL).Result:
                            print 1
                        ");

            await urls.ForEachAsync(20, async line =>
            {
                try
                {

                    var adderEngine = new SpeedEngine();
                  //  int zz = await adderEngine.Open(line);
                   // return;
                        ScriptScope scope = engine.CreateScope();

                        scope.SetVariable("__URL", line);

                        scope.SetVariable("Open",
                            new Func<string, Task<int>>(adderEngine.Open));
                    try
                    {
                        await scriptSource.Execute(scope);
                    }
                    catch (UnboundNameException une)
                    {
                        MessageBox.Show(une.Message,
                            msg.
                                MySeoBoxForm_startPostingToolStripButton_Click_Unbound_Name_Error,
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (SyntaxErrorException see)
                    {
                        MessageBox.Show(
                            string.Format("{0}\nLine: {1}\nCode: {2}",
                                see.Message,
                                see.Line, see.GetCodeLine()),
                            msg.
                                MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (MissingMemberException mme)
                    {
                        MessageBox.Show(mme.Message, "Missing Member",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (ArgumentTypeException ate)
                    {
                        MessageBox.Show(string.Format("{0}", ate.Message),
                            msg.
                                MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (SystemExitException)
                    {

                    }
                    catch (Exception exc)
                {
                     MessageBox.Show(string.Format("{0}", exc.Message),
                       msg.
                           MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
                       MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                    finally
                    {

                     MessageBox.Show(string.Format("{0}","OK"),
                       msg.
                           MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
                       MessageBoxButtons.OK, MessageBoxIcon.Error);

                    }

                }
                catch (Exception exc)
                {
                     MessageBox.Show(string.Format("{0}", exc.Message),
                       msg.
                           MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
                       MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                finally
                {
                    Interlocked.Increment(ref finishedUrls);
                    numericUpDown1.Invoke(new MethodInvoker(delegate
                    {
                        numericUpDown1.Value++;
                    }));
                }

            });
            timerPostingSpeed.Dispose();
        }

    }

   public async Task<int> Open(string siteUrl)
        {
                Uri newUri;
                if (!Uri.TryCreate(siteUrl, UriKind.Absolute, out newUri)) return 0;
                _uri = _openUri = newUri;
                _req = new HttpRequestMessage(HttpMethod.Get, _uri);

                _response = await _httpClient.SendAsync(_req);

                if (_response == null || !_response.IsSuccessStatusCode)
                {
                  return 0;
                }


                return 1;
        }

我需要使用 Iron Python - 没有它(当我取消注释await adderEngine.Open(line); return;)一切正常。但是使用 Iron Python,我的应用程序在 *_response = await _httpClient.SendAsync(_req);* 处停止,没有错误。我也注意到当我更换

await urls.ForEachAsync(20, async line =>

和:

await urls.ForEachAsync(1, async line =>

它正在工作

ForEachAsync:http: //blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx

有什么帮助吗?

4

1 回答 1

4

如果您的 Python 代码正在调用Task.Result,并且您在 UI 线程上(似乎是这种情况),则可能会导致死锁(我在我的博客上对此进行了充分解释)。简而言之,async方法 ( Open) 试图在 UI 线程上恢复执行,但 UI 线程被调用阻塞Result

AFAIK,Python 没有async/await支持,但您应该能够使用(meh)或在TwistedContinueWith之间编写某种桥梁(更酷)。TaskDeferred

于 2013-10-29T21:59:27.897 回答