Вопрос был:
Как вернуть ответ от асинхронного вызова?
, который может быть интерпретирован как:
Как сделать синхронный асинхронный код синхронным?
Решение будет состоять в том, чтобы избежать обратных вызовов и использовать комбинацию Promises и async / await.
Я хотел бы привести пример для запроса Ajax.
(Хотя он может быть записан в Javascript, я предпочитаю писать его на Python и компилировать его в Javascript, используя Transcrypt . Это будет достаточно ясно.)
Позволяет сначала включить использование JQuery, чтобы
$
был доступен какS
:__pragma__ ('alias', 'S', '$')
Определить функцию, которая возвращает Promise, в этом случае вызов Ajax:
def read(url: str): deferred = S.Deferred() S.ajax({'type': "POST", 'url': url, 'data': { }, 'success': lambda d: deferred.resolve(d), 'error': lambda e: deferred.reject(e) }) return deferred.promise()
Использовать асинхронный код, как если бы он был синхронным:
async def readALot(): try: result1 = await read("url_1") result2 = await read("url_2") except Exception: console.warn("Reading a lot failed")
string tempDirectory = Session.SessionID.ToString();
string location = Path.Combine(Server.MapPath(
WebConfigurationManager.AppSettings["PathSet"].ToString()), tempDirectory);
if (!Directory.Exists(location))
{
Directory.CreateDirectory(location);
}
string fileName="abc.pdf";
filePath = Path.Combine(location, fileName);
Я собираюсь объединить ответ каждого в один, который вы сможете зайти и использовать. Если это сработает, я бы принял ответ Маниша Парахии, потому что это имело самую важную роль.
Во-первых, я предполагаю, что вы используете последнюю версию iTextSharp. Я думаю, 5.5.5 - самая последняя версия. Во-вторых, из-за этого я немного перестрою ваш код, чтобы использовать шаблон using
. Если вы застряли в старой устаревшей неподдерживаемой версии, такой как 4.1.6, вам нужно будет отрегулировать ее.
Практически в каждом учебном пособии показано, что вы можете напрямую связать Response.OutputStream
. Это на 100% действительно, но я бы сказал, что это тоже очень плохая идея. Вместо этого свяжитесь с более общим MemoryStream
. Это значительно облегчает отладку, и ваш код будет намного легче переносить и адаптировать.
В приведенном ниже коде содержатся комментарии о каждом из изменений и о том, что на самом деле делает. Верхний раздел посвящен созданию PDF-файла из строки HTML. Дно на самом деле что-то делает с ним, включая запись на диск и / или передачу его в браузер.
//Will hold our PDF eventually
Byte[] bytes;
//HTML that we want to parse
string html = "<table><tr><td>some contents</td></tr></table>";
//Create a MemoryStream to write our PDF to
using (var ms = new MemoryStream()) {
//Create our document abstraction
using (var ResultPDF = new Document(iTextSharp.text.PageSize.A4, 25, 10, 20, 30)) {
//Bind a writer to our Document abstraction and our stream
using (var writer = PdfWriter.GetInstance(ResultPDF, ms)) {
//Open the PDF for writing
ResultPDF.Open();
//Parse our HTML using the old, obsolete, not support parser
using (var sw = new StringWriter()) {
using (var hw = new HtmlTextWriter(sw)) {
using (var sr = new StringReader(html)) {
using (var htmlparser = new HTMLWorker(ResultPDF)) {
htmlparser.Parse(sr);
}
}
}
}
//Close the PDF
ResultPDF.Close();
}
}
//Grab the raw bytes of the PDF
bytes = ms.ToArray();
}
//At this point, the bytes variable holds a valid PDF file.
//You can write it disk:
System.IO.File.WriteAllBytes("your file path here", bytes);
//You can also send it to a browser:
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=WelcomeLetter.pdf");
Response.BinaryWrite(bytes);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
//Never do the next line, it doesn't do what you think it does and actually produces corrupt PDFs
//Response.Write(ResultPDF); //BAD!!!!!!
Response.End();
Для сохранения файла pdf локально в папке проекта вы можете использовать класс FileStream
следующим образом.
FileStream stream = new FileStream(filePath, FileMode.Create);//Here filePath is path of your project folder.
Теперь используйте этот поток вместо использования Response.OutputStream
при создании экземпляра PdfWriter
object.
PdfWriter.GetInstance(ResultPDF, stream);
Теперь не используйте Responce.Write
, так как вы не хотите загружать файл. И завершите свой поток в конце.
stream.Close();