主頁 > .NET開發 > 除錯/修復“超過最大執行時間”錯誤GoogleAddon

除錯/修復“超過最大執行時間”錯誤GoogleAddon

2022-03-13 19:29:47 .NET開發

我已經創建了我的第一個 Google Workspace 插件,我已成功部署到相關域,但由于此錯誤仍在處理它。

沒有錯誤,在功能上它(曾經)運行良好,但是,我現在不斷收到“超過最大執行時間”錯誤。

這個錯誤是令人沮喪的斷斷續續的,但它最近開始出現大約 90% 以上的時間,盡管之前幾周都沒有發生過。恢復到我的代碼的以前版本并沒有解決問題。

大多數(如果不是全部)關于此錯誤的現有答案都假定腳本確實超過了腳本的時間限制(6 分鐘或 30 分鐘)。

需要明確的是 - 這不是這里發生的事情。該腳本不會在接近允許的最大時間的任何地方運行(據我所知)。在給出錯誤之前它實際上運行了大約 45 秒。

它可能以某種方式在后臺運行并導致合法的超時錯誤,但我需要弄清楚是否是這種情況以及錯誤的原因,然后修復它。

我已經聯系了谷歌,但不幸的是,他們的相關支持人員非常了解這一點并且可以提供幫助。

在針對此錯誤的 Cloud Logging 中,我看到(混淆的 id):

{
  "insertId": "28z8v2anf1xq6",
  "jsonPayload": {
    "context": {
      "reportLocation": {
        "filePath": "[unknown file]",
        "functionName": "[unknown function]"
      }
    },
    "message": "Exceeded maximum execution time",
    "serviceContext": {
      "service": "AKfycbx-SO5mXBNoe2leEH4wrj02t9fZZwkq5BQlJPuBaNM"
    }
  },
  "resource": {
    "type": "app_script_function",
    "labels": {
      "function_name": "fileMakerPro",
      "invocation_type": "unknown",
      "project_id": "order-management-713317"
    }
  },
  "timestamp": "2022-03-10T10:09:58.827Z",
  "severity": "ERROR",
  "labels": {
    "script.googleapis.com/process_id": "fIxbX5X5IjrIqLLK-XQgJiJV0U9vQMEAEA1GOxTqw-XzqsaVlKTNK2UcymM7feuXp-qZLshvBUg61TS6u28l_v6szoAq8QBBOvGudISVj0yceQXPKpIHO6HJ2G-uxuqy4xcnv-NzDfBTMbJH7VmK_AjZd6a5KVA-LnhtOE_28mCn_zTpI5AC3-BhX_lcCC1p-3QsMX6blhMZSYgVTTo1T_Z9SovufUWinpJieIbio-L8wzQPkjLYM2l9s5RHGuKMcT3LbvUO7fFS4DV1z_xfaR_nU1LqeayAk1aouGSXc",
    "script.googleapis.com/user_key": "wPo7ZL4DSIqpPrZfeqo7E7yAArA430YCNnzbVYhyuVlR6nKybMkISeaDZoigRDx0gAJXIjF49EoL",
    "script.googleapis.com/deployment_id": "wkq5BQlJPcbx-SO5mEHAKfywrj02t9fZZ4uBXBNoe2leaNM",
    "script.googleapis.com/project_key": "Xf9t90MIwJJbMnu2Z9hQ48TM6DPTcW9w3"
  },
  "logName": "projects/order-management-317713/logs/script.googleapis.com/console_logs",
  "receiveTimestamp": "2022-03-10T10:09:59.313440894Z"
}

這是晦澀難懂的,對“未知數”根本沒有幫助。

它參考的函式,供參考:

async function fileMakerPro(e) {
  console.time("fileMakerPro");

  //Order Management Named Ranges
  let OM_NR = await getNamedRangesAsObject_(ss);
  
  let orderNumber, orderFolder, orderFolderName;
  let loadingDate, loadingDateFormatted, dueDate, dueDateFormatted;

  let sheetGoodsTable = OM_NR.goodsTable.ranges.filter(function (x) { /* here, x is an array, not an object */
    return !(x.every(element => element === (undefined || null || '')))
  });

  //Get order number if exists or show warning and return
  if (orderNumber = OM_NR.OrderNo.range.toString()) {

  } else {
    ui.alert(`??  ORDER NUMBER \(${OM_NR.OrderNo.rangeA1.toString()}\) appears missing, please correct and try again.`);
    return;
  }
  //Get loading date if exists or show warning and return
  if (loadingDate = OM_NR.transportLoadingDate.range) {

    loadingDateFormatted = `${loadingDate.getDate()}-${loadingDate.getMonth()   1}-${loadingDate.getFullYear()}`;
    monthName = monthNames[loadingDate.getMonth()];

    //Set Due Date 30 days after Loading Date
    dueDate = new Date(loadingDate.getFullYear(), loadingDate.getMonth(), loadingDate.getDate()   30);
    dueDateFormatted = `${dueDate.getDate()}-${dueDate.getMonth()   1}-${dueDate.getFullYear()}`;


  } else {
    ui.alert(`?? LOADING DATE \(${OM_NR.transportLoadingDate.rangeA1.toString()}\) appears to be missing, please correct and try again.`);
    return;
  }

  let rootFolder = DriveApp.getFileById(sheetId).getParents().next();
  let tempFolder = DriveApp.getFolderById("1f4Ll-KODzmvBIuunaCS_7anMCX-w86S6");
  let monthFolders = rootFolder.getFolders();
  let tickBoxes = e.formInputs.generateDocsCheckboxes;


  let packingListTemplateId = '1cZUB4U59Z56456gdgdghhka2QQ9sUNIlQSHYy1M';
  let tickCMR = false, tickInvoice = false;

  //Find existing order folder
  let orderSearch = await searchFolders(monthFolders, monthName, orderNumber);

  //Set Order Folder Name if both values present
  orderFolderName = `${loadingDate.getDate()}-${loadingDate.getMonth()   1}-${loadingDate.getFullYear()} \(${orderNumber}\)`;


  if (tickBoxes !== undefined) {
    if (tickBoxes.indexOf('tickBoxCMRnote') > -1) {
      tickCMR = true;
    }
    if (tickBoxes.indexOf('tickBoxInvoice') > -1) {
      tickInvoice = true;
    }
  } else {
    let confirm = ui.alert(`?? No documents selected. Update Order ${orderNumber} Snapshot and Packing List only?`, Browser.Buttons.YES_NO);
    if (confirm === ui.Button.YES) {
      fileMakerPro();
    } else {
      ss.toast(`?? Update cancelled.`);
      return;
    }
  }

  if (!orderSearch.foundMonthFolder) {
    ss.toast(`?? Creating Month Folder...`);
    monthFolder = rootFolder.createFolder(monthName);
  } else {
    monthFolder = orderSearch.foundMonthFolder;
  }

  if (!orderSearch.foundOrderFolder) {
    ss.toast(`?? Creating Order Folder...`);
    orderFolder = monthFolder.createFolder(orderFolderName);
  } else {
    if (!orderSearch.foundOrderFolder.getName().includes(loadingDateFormatted)) {
      ui.alert(`?? Duplicate Order Number ${orderNumber} found: ${orderSearch.foundMonthFolder.getName()} / ${orderSearch.foundOrderFolder.getName()}.\n\n Please change Order Number or remove duplicate Order Folder.`);
      return;
    }
    orderFolder = orderSearch.foundOrderFolder;
  }


  if (tickInvoice && tickCMR) {
  
      assembleCMR(orderFolder, orderNumber, tempFolder, loadingDateFormatted, sheetGoodsTable, OM_NR);
      assembleInvoice(orderFolder, orderNumber, tempFolder, loadingDateFormatted, dueDateFormatted, sheetGoodsTable, OM_NR);

      ss.toast(`? Documents Saved`);


  } else {
    if (tickCMR) {

        assembleCMR(orderFolder, orderNumber, tempFolder, loadingDateFormatted, sheetGoodsTable, OM_NR);

        ss.toast(`? CMR Document Saved`);

    }
    if (tickInvoice) {

        assembleInvoice(orderFolder, orderNumber, tempFolder, loadingDateFormatted, dueDateFormatted, sheetGoodsTable, OM_NR);

        ss.toast(`? Invoice Document Saved`);

    }
  }

  let existingOrderSnapshot = orderFolder.getFilesByName(`${orderNumber} - ORDER SNAPSHOT - DO NOT EDIT`);
  let existingPackingList = orderFolder.getFilesByName(`${orderNumber} - PACKING LIST`);

  let packingListId = await createPackingList(existingPackingList, orderFolder, orderNumber, packingListTemplateId, sheetId, OM_NR);

  
  createOrderSnapshot(existingOrderSnapshot, orderFolder, orderNumber, sheetId, packingListId);

  syncOrderNumbers(orderSearch.orderNumbers);


  console.timeEnd("fileMakerPro");

  return;
}

I suspect maybe the following function could be causing the Timeout since the loop may be malfunctioning but not sure how to check or fix:

async function writePackingList(OM_NR, packingList, packingListId){
    let PL_NR = await getNamedRangesAsObject_(packingList);

    for (let nr in PL_NR) {
      Logger.log(nr);

      if (nr == "loadingAddress") {
        packingList.getRangeByName(`${nr}`).setValue(OM_NR[`${nr}`].range);
      } else if (nr) {
        packingList.getRangeByName(`${nr}`).setValue(OM_NR[`${nr}`].range);
      } else {
        break;
      }
    }

    ss.getRangeByName("transportTotalNetWeight").setFormula(`=IMPORTRANGE("${packingListId}", "PL!I15")`)
    ss.getRangeByName("transportTotalGrossWeight").setFormula(`=IMPORTRANGE("${packingListId}", "PL!H15")`)
}

Any help would be appreciated as I've hit a brick wall with this. I need to figure out how to debug this error, understand why it's happening and fix it so it doesn't happen when fully deployed.

Thanks

EDIT to include additional functions:

//Make copy of Invoice template doc, get body, replace all placeholders, return 
async function assembleInvoice(orderFolder, orderNumber, tempFolder, loadingDateFormatted, dueDateFormatted, sheetGoodsTable, OM_NR) {
  console.time("assembleInvoice");

  ss.toast(`?? Assembling Invoice Document...`);
  let prefix = orderNumber   " - ";
  let fileName = "INVOICE";
  let templateTempCopy;

  //Blue Invoice Template
  let invoiceTemplate1 = DriveApp.getFileById("C2j_q3nUP4UTUR1KiCt07r1lATPKSjzEm-EeY109T8B4");
  //Red Invoice Template
  let invoiceTemplate2 = DriveApp.getFileById("1uczJT-F-JzKzaBwh_CdhJNcFkgDHfGjypJYom4vqGIo");

  //Choose Invoice template based on Movement Type
  let staraMovementType = OM_NR.staraMovementType.range;


  if (staraMovementType.toString().includes('GB SHIPPING TO')) {
    templateTempCopy = invoiceTemplate1.makeCopy(tempFolder);
  } else {
    templateTempCopy = invoiceTemplate1.makeCopy(tempFolder);
  }


  //Open working copy
  let workingCopy = DocumentApp.openById(templateTempCopy.getId());

  //Get body from working copy
  let documentBody = workingCopy.getBody();


  //Populate table
  let allTables = documentBody.getTables();
  let invoiceGoodsTable = allTables[3];

  let itemRowTemplate = invoiceGoodsTable.getRow(invoiceGoodsTable.getNumRows() - 2);
  let totalsRowTemplate = invoiceGoodsTable.getRow(invoiceGoodsTable.getNumRows() - 1);


  for (let n in sheetGoodsTable) {
    let tableRow = invoiceGoodsTable.appendTableRow(itemRowTemplate.copy());

    tableRow.getCell(0).replaceText("{itemNo}", sheetGoodsTable[n][1]);
    tableRow.getCell(1).replaceText("{itemDesc}", sheetGoodsTable[n][0]);
    tableRow.getCell(2).replaceText("{commodityCode}", sheetGoodsTable[n][2]);
    tableRow.getCell(3).replaceText("{cartons}", sheetGoodsTable[n][4]);
    tableRow.getCell(4).replaceText("{qtyKgs}", sheetGoodsTable[n][5]);
    tableRow.getCell(5).replaceText("{price}", sheetGoodsTable[n][3]);
    tableRow.getCell(6).replaceText("{total}", sheetGoodsTable[n][5] * sheetGoodsTable[n][3]);
  }

  let totalsRow = invoiceGoodsTable.appendTableRow(totalsRowTemplate.copy());

  totalsRow.getCell(3).replaceText("{cartons}", OM_NR.transportCasesCartons.range);
  totalsRow.getCell(4).replaceText("{qtyKgs}", OM_NR.transportTotalNetWeight.range);
  totalsRow.getCell(6).replaceText("{total}", OM_NR.transportInvoiceTotal.range);


  itemRowTemplate.removeFromParent();
  totalsRowTemplate.removeFromParent();

  let importerAddress = `${OM_NR.importerConsigneeIntoEU.range}, ${OM_NR.importerAddress.range}`;

  documentBody.replaceText("{currency}", OM_NR.staraInvoiceCurrency.range);

  documentBody.replaceText("{shipToAddress}", importerAddress);

  documentBody.replaceText("{billToAddress}", importerAddress);

  documentBody.replaceText("{exporterCustomsInvoiceNo}", OM_NR.exporterCustomsInvoiceNo.range);

  documentBody.replaceText("{exporterVAT}", OM_NR.exporterVAT.range);
  documentBody.replaceText("{exporterEORI}", OM_NR.exporterEORI.range);
  documentBody.replaceText("{staraOrderNo}", OM_NR.staraOrderNo.range);
  documentBody.replaceText("{staraCustomerOrderNo}", OM_NR.staraCustomerOrderNo.range);
  documentBody.replaceText("{transportLoadingDate}", loadingDateFormatted);

  documentBody.replaceText("{dueDate}", dueDateFormatted);

  documentBody.replaceText("{paymentTerms}", "30 DAYS");
  documentBody.replaceText("{staraInvoiceNo}", OM_NR.staraInvoiceNo.range);

  documentBody.replaceText("{incoTerms}", `${OM_NR.orderIncoterm.range} ${OM_NR.orderCountryOfDestination.range}`);
  documentBody.replaceText("{transportTotalGrossWeight}", OM_NR.transportTotalGrossWeight.range);
  documentBody.replaceText("{transportTotalNetWeight}", OM_NR.transportTotalNetWeight.range);

  documentBody.replaceText("{transportTruckRef}", OM_NR.transportTruckRef.range);
  documentBody.replaceText("{transportSeal1}", OM_NR.transportSeal1.range);
  documentBody.replaceText("{transportSeal2}", OM_NR.transportSeal2.range);

  documentBody.replaceText("{transportInvoiceTotal}", OM_NR.transportInvoiceTotal.range);
  documentBody.replaceText("{staraInvoiceCurrency}", OM_NR.staraInvoiceCurrency.range);


  workingCopy.saveAndClose();


  //Gets a 'blob' of the completed document
  let completedDoc = templateTempCopy.getAs('application/pdf');

  //Check for existing PDF and move to trash (not fully delete)
  let foundFile = orderFolder.getFilesByName(prefix   fileName);
  if (foundFile.hasNext()) {
    foundFile.next().setTrashed(true);
  }

  try {
    //Create PDF
    ss.toast(`?? Saving ${fileName} PDF...`);

    orderFolder.createFile(completedDoc).setName(prefix   fileName);

    deleteTempFiles(templateTempCopy.getId());

  } catch (err) {
    showError(err);
  } finally {
    ss.toast(`? Invoice Document Saved`);
    console.timeEnd("assembleInvoice");

  }
  return;
}
async function createPackingList(existingPackingList, orderFolder, orderNumber, packingListTemplateId, sheetId, OM_NR) {
  console.time("createPackingList");

    let packingListId;
    //Get current sheet container objects and data
    if (existingPackingList.hasNext()) {
      packingListId = existingPackingList.next().getId();
    } else {
      ss.toast(`?? Creating Packing List...`);
      let newPackingList = DriveApp.getFileById(packingListTemplateId);
      let newPackingListCopy = newPackingList.makeCopy(`${orderNumber} - PACKING LIST`, orderFolder)
      packingListId = newPackingListCopy.getId();
    }

    let packingList = SpreadsheetApp.openById(packingListId);
    addImportrangePermission(packingListId, sheetId);

    writePackingList(OM_NR, packingList, packingListId);


    ss.toast(`? Packing List Created/Updated`);
    console.timeEnd("createPackingList");
    return packingListId;
}
async function createOrderSnapshot(existingOrderSnapshot, orderFolder, orderNumber, sheetId, packingListId) {
  console.time("createOrderSnapshot");

  let snapshotExists = existingOrderSnapshot.hasNext();

    //If snapshot exists, delete.
    if (snapshotExists) {
      existingOrderSnapshot.next().setTrashed(true);
      ss.toast(`?? Updating Order Snapshot...`);
    } else {
      ss.toast(`?? Creating Order Snapshot...`);
    }

    //Make copy of sheet in order folder
    let currentSheet =  DriveApp.getFileById(sheetId);
    let sheetCopy = currentSheet.makeCopy(`${orderNumber} - ORDER SNAPSHOT - DO NOT EDIT`, orderFolder);
    let sheetCopyId = sheetCopy.getId();
    let targetSpreadsheet = SpreadsheetApp.openById(sheetCopyId);
    

    //let targetSpreadsheet = SpreadsheetApp.openById(DriveApp.getFileById(sheetId).makeCopy(`${orderNumber} - ORDER SNAPSHOT - DO NOT EDIT`, orderFolder).getId());

    addImportrangePermission(targetSpreadsheet.getRangeByName("CONTROL").getValue(), sheetCopyId);
    addImportrangePermission(packingListId, sheetCopyId);

    targetSpreadsheet.getRangeByName("transportTotalNetWeight").setFormula(`=IMPORTRANGE("${packingListId}", "PL!I15")`)
    targetSpreadsheet.getRangeByName("transportTotalGrossWeight").setFormula(`=IMPORTRANGE("${packingListId}", "PL!H15")`)

    targetSpreadsheet.getRangeByName("topRow").clearDataValidations()
    targetSpreadsheet.getRangeByName("sheetBody").clearDataValidations()

    //DELETE UNNEEDED TABS FROM COPY
    targetSpreadsheet.deleteSheet(targetSpreadsheet.getSheetByName("PC"));
    targetSpreadsheet.deleteSheet(targetSpreadsheet.getSheetByName("C1"));
    targetSpreadsheet.deleteSheet(targetSpreadsheet.getSheetByName("C2"));
    targetSpreadsheet.deleteSheet(targetSpreadsheet.getSheetByName("SFC"));


    if (snapshotExists) {
      ss.toast(`? Order Snapshot Updated`);
    } else {
      ss.toast(`? Order Snapshot Created`);
    }
    console.timeEnd("createOrderSnapshot");
  
  return;
}
async function addImportrangePermission(sourceSheetId, authSheetId) {
  console.time("addImportrangePermission");
  if (sourceSheetId) {
    // donor or source spreadsheet id

    // adding permission by fetching this url
    let url = `https://docs.google.com/spreadsheets/d/${authSheetId}/externaldata/addimportrangepermissions?donorDocId=${sourceSheetId}`;

    let token = ScriptApp.getOAuthToken();

    let params = {
      method: 'post',
      headers: {
        Authorization: 'Bearer '   token,
      },
      muteHttpExceptions: true
    };

    UrlFetchApp.fetch(url, params);
  }
  console.timeEnd("addImportrangePermission");
  return;
}

uj5u.com熱心網友回復:

問題:

在 Workspace 插件中,Action觸發時執行的回呼函式被限制為30 秒的執行時間

Apps 腳本卡服務將回呼函式限制為最長 30 秒的執行時間。如果執行時間超過此時間,您的附加 UI 可能無法正確更新其卡片顯示以回應Action

筆記:

由于您沒有提供與花費最多時間的功能相關的代碼(例如assembleCMR, assembleInvoice, createPackingList),因此我無法對此提出任何建議,但無論如何您應該嘗試提高這些功能的效率,或者將其全部拆分為幾個Actions

參考:

  • 回呼函式

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/442358.html

標籤:google-apps-script google-workspace-add-ons

上一篇:如何將上傳到谷歌表單的影像移動到單獨的單獨檔案夾中?

下一篇:GoogleApps腳本:如何加快將大資料從一個檔案復制到另一個檔案的速度?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more