Необходимо будет удостовериться, что обновление происходит на корректном потоке; поток UI.
, Чтобы сделать это, необходимо будет Вызвать обработчик событий вместо того, чтобы назвать его непосредственно.
можно сделать это путем генерирования события как это:
(Код введен здесь из моей головы, таким образом, я не проверил на правильный синтаксис, и т.д., но это должно получить Вас движение.)
if( MyEvent != null )
{
Delegate[] eventHandlers = MyEvent.GetInvocationList();
foreach( Delegate d in eventHandlers )
{
// Check whether the target of the delegate implements
// ISynchronizeInvoke (Winforms controls do), and see
// if a context-switch is required.
ISynchronizeInvoke target = d.Target as ISynchronizeInvoke;
if( target != null && target.InvokeRequired )
{
target.Invoke (d, ... );
}
else
{
d.DynamicInvoke ( ... );
}
}
}
Примечание, что код выше не будет работать над проектами WPF, начиная со средств управления WPF, не реализует эти ISynchronizeInvoke
интерфейс.
, Чтобы удостовериться, что код выше работ с Windows Forms и WPF и всеми другими платформами, можно взглянуть на AsyncOperation
, AsyncOperationManager
и SynchronizationContext
классы.
, Чтобы легко сгенерировать события этот путь, я создал дополнительный метод, который позволяет мне упрощать генерирование события, просто звоня:
MyEvent.Raise(this, EventArgs.Empty);
, Конечно, можно также использовать класс BackGroundWorker, который абстрагирует этот вопрос для Вас.
Вам не нужно связываться с STDOUT
; CGI-App должно правильно справиться с этим за вас. Вам также может потребоваться закрыть дескриптор файла перед попыткой отправки данных.
Однако похоже, что вы не устанавливаете правильный тип содержимого для данных Excel. Для всего, кроме text / html, вам нужно будет установить его вручную. Попробуйте что-то вроде этого:
sub export_list {
my $self = shift;
my $str;
open my $fh, '>', \$str or die "Can't open to var: $!";
my $workbook = Spreadsheet::WriteExcel->new($fh);
my $worksheet = $workbook->add_worksheet();
$worksheet->write_col(0,0, ['some','data','here']);
$workbook->close;
close $fh;
warn $str;
$self->header_add( -type => 'application/vnd.ms-excel' );
return $str;
}
Вас также может заинтересовать CGI :: Application :: Plugin :: Stream
Вместо того, чтобы создавать всю электронную таблицу в памяти, вы должны либо записать ее в файл, либо они передают его по завершении (здесь помогает CGI :: Application :: Plugin :: Stream , но вам все равно нужно будет очистить его после этого, но на самом деле каждое веб-приложение должно иметь временный каталог, который периодически очищается) или распечатайте его по мере создания (что означает создание FH STDIN
вместо этого, что может быть сложнее с mod_perl, а может и нет).
А затем не забудьте закрыть свою книгу, когда это будет сделано.
Вы хотите закрыть книгу. Также закройте дескриптор файла:
warn "length 1=".length($str);
$workbook->close();
close($fh) or die "error on close: $!";
warn "length 2=".length($str);
length 1=0 at wx.pl line 16.
length 2=5632 at wx.pl line 19.