使用 Iron Python 等待异步

eka*_*pek 2 c# asynchronous

现在,我使用并行方法来检查 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;
        }
Run Code Online (Sandbox Code Playgroud)

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

await urls.ForEachAsync(20, async line =>
Run Code Online (Sandbox Code Playgroud)

和:

await urls.ForEachAsync(1, async line =>
Run Code Online (Sandbox Code Playgroud)

它正在工作

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

有什么帮助吗?

Ste*_*ary 5

如果您的 Python 代码正在调用Task.Result,并且您位于 UI 线程上(看起来就是这种情况),则可能会导致死锁(我在我的博客上详细解释了这一点)。简而言之,async方法 ( Open) 试图在 UI 线程上恢复执行,但 UI 线程因调用而被阻塞Result

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