顯示具有 VSTO 標籤的文章。 顯示所有文章
顯示具有 VSTO 標籤的文章。 顯示所有文章

2012-03-11

偵測到 ContextSwitchDeadlock

程式用迴圈長時間處理Excel 檔結果出現以下訊息。


偵測到 ContextSwitchDeadlock
---
CLR 在過去 60 秒一直無法從 COM 內容 0x16ce00 轉換為 COM 內容 0x16cbd8。擁有該目的內容/Apartment 的執行緒,很可能正在進行非提取等候或正在處理非常長的執行作業,而未提取 Windows 訊息。這種情況通常會對效能產生負面影響,甚至可能導致應用程式停止回應,或導致記憶體使用量持續隨時間而累積。若要避免這個問題,所有單一執行緒的 Apartment (STA) 執行緒都應該使用提取等候基本方法 (例如 CoWaitForMultipleHandles),並且在長時間的執行作業中定期提取訊息。



這個訊息只會在偵錯時出現,發佈的後並不會有,所以可以按繼績不理會。
如果確定程式沒有錯誤,又不想讓它顯示,可以透過以下選項取消讓它不顯示。
Debug -> Exceptions -> Managed Debug Assistants 去掉ContextSwitchDeadlock的勾選
偵錯 -> 例外狀況 -> Managed Debug Assistants 去掉 ContextSwitchDeadlock 的撙回項目勾選

VSTO Excel Copy row to another worksheet


//複製資料
Excel.Range srcRange = wsSrc.Rows[target.Row] as Excel.Range;
Excel.Range destRange = wsDest.Rows[dest.Row] as Excel.Range;
destRange.Value2 = srcRange.Value2;

//複製無formulas
Object template = Settings.Default.TemplatePath;
Workbook wb = Globals.ThisAddIn.Application.Workbooks.Add(template) as Workbook;
Excel.Range r = (Excel.Range)wb.Application.ActiveCell[1, "A"];
const int xlShiftDown = -4121;
Excel.Range oRow = r.EntireRow;
oRow.Insert(xlShiftDown, Excel.XlInsertFormatOrigin.xlFormatFromRightOrBelow);


//複製有formulas
Object template = Settings.Default.TemplatePath;
Excel.Workbook wb = Globals.ThisAddIn.Application.Workbooks.Add(template)
    as Excel.Workbook;
Excel.Range r = (Excel.Range)wb.Application.ActiveCell[1, "A"];
Excel.Range oRow = r.EntireRow;
oRow.Select();
oRow.Copy();
Excel.Range rg = (Excel.Range)rg[2, "A"];
rg.Select();
rg.PasteSpecial(Excel.XlPasteType.xlPasteAll,
    Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone,
    Type.Missing,
    Type.Missing);
wb.Application.CutCopyMode = Excel.XlCutCopyMode.xlCopy;

2012-03-10

Excel.Range To Array, Array To Excel.Range

Range to Array



        private void btnRange2Array_Click(object sender, EventArgs e)

        {
            Excel.Worksheet ws = (Excel.Worksheet)Globals.ThisAddIn.Application.ActiveSheet;
            Excel.Range r = ws.get_Range("A1", "B3");
            System.Array arr = (System.Array)r.Value2;
            string[] ar= new string[arr.Length];
            int i = ar.GetLowerBound(0);
            foreach (var item in arr)
                ar[i++] = item!=null? item.ToString():String.Empty;

            txtResults.Text = String.Join(",", ar);

        }



Array to Range




        private void btnArray2Range_Click(object sender, EventArgs e)
        {
            string[,] arr = new string[,] { {"AA", "BB"}, {null,"DD"},{"EE","FF"}};
            Excel.Worksheet ws = (Excel.Worksheet)Globals.ThisAddIn.Application.ActiveSheet;
            Excel.Range r = ws.get_Range("A1", "B3");
            r.Value2 = arr;
        }


adsense