Почему цикл событий asyncio подавляет KeyboardInterrupt в Windows?

Вопрос заключается в том, чтобы во время создания файла отображался индикатор ожидания, а затем возвращался к нормальному состоянию после загрузки файла. Как мне нравится делать это, используйте скрытый iFrame и подключайте событие onload к фрейму, чтобы моя страница знала, когда начнется загрузка. НО загрузка не запускается в IE для загрузки файлов (например, с токеном заголовка вложения). Опрос сервера работает, но мне не нравится дополнительная сложность. Итак, вот что я делаю:

  • Задайте скрытый iFrame, как обычно.
  • Создайте контент. Загрузите его с абсолютным таймаутом через 2 минуты.
  • Отправьте javascript на перенаправление обратно вызывающему клиенту, по существу вызывающему страницу генератора во второй раз. ПРИМЕЧАНИЕ: это приведет к тому, что событие onload будет запущено в IE, потому что оно действует как обычная страница.
  • Удалить содержимое из кеша и отправить его клиенту.

Отказ от ответственности, не делайте этого на загруженном сайте, из-за того, что кеширование может складываться. Но на самом деле, если ваши сайты, занятые длительным запуском процесса, будут голодать в любом случае.

Вот что выглядит codebehind, что вам действительно нужно.

public partial class Download : System.Web.UI.Page
{
    protected System.Web.UI.HtmlControls.HtmlControl Body;

    protected void Page_Load( object sender, EventArgs e )
    {
        byte[ ] data;
        string reportKey = Session.SessionID + "_Report";

        // Check is this page request to generate the content
        //    or return the content (data query string defined)
        if ( Request.QueryString[ "data" ] != null )
        {
            // Get the data and remove the cache
            data = Cache[ reportKey ] as byte[ ];
            Cache.Remove( reportKey );

            if ( data == null )                    
                // send the user some information
                Response.Write( "Javascript to tell user there was a problem." );                    
            else
            {
                Response.CacheControl = "no-cache";
                Response.AppendHeader( "Pragma", "no-cache" );
                Response.Buffer = true;

                Response.AppendHeader( "content-disposition", "attachment; filename=Report.pdf" );
                Response.AppendHeader( "content-size", data.Length.ToString( ) );
                Response.BinaryWrite( data );
            }
            Response.End();                
        }
        else
        {
            // Generate the data here. I am loading a file just for an example
            using ( System.IO.FileStream stream = new System.IO.FileStream( @"C:\1.pdf", System.IO.FileMode.Open ) )
                using ( System.IO.BinaryReader reader = new System.IO.BinaryReader( stream ) )
                {
                    data = new byte[ reader.BaseStream.Length ];
                    reader.Read( data, 0, data.Length );
                }

            // Store the content for retrieval              
            Cache.Insert( reportKey, data, null, DateTime.Now.AddMinutes( 5 ), TimeSpan.Zero );

            // This is the key bit that tells the frame to reload this page 
            //   and start downloading the content. NOTE: Url has a query string 
            //   value, so that the content isn't generated again.
            Body.Attributes.Add("onload", "window.location = 'binary.aspx?data=t'");
        }
    }
23
задан dano 16 December 2014 в 16:25
поделиться

1 ответ

Если вы просто хотите выйти из программы и вам не нужно перехватывать KeyboardInterrupt, модуль сигнала обеспечивает более простой (и более эффективный) обходной путь:

# This restores the default Ctrl+C signal handler, which just kills the process
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

# Now the event loop is interruptable
import asyncio
asyncio.get_event_loop().run_forever()
9
ответ дан Bart Robinson 16 December 2014 в 16:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: