简体   繁体   English

线程安全ReferenceEquals

[英]Thread safe ReferenceEquals

I try to create an VSTO Addin. 我尝试创建一个VSTO加载项。 Within this I store Worksheet objects in a list. 在其中,我将工作表对象存储在列表中。 For my Addin it is important to use a delayed function call to execute it in a own Thread. 对于我的Addin,使用延迟的函数调用在自己的线程中执行它很重要。 So when I call TestClass.run() I go 2 times through my list of worksheets, first before calling the delayed function and second within the delayed function. 因此,当我调用TestClass.run()我会遍历工作表列表两次,第一次是在调用延迟函数之前,其次是在延迟函数中。 The second call cannot match the worksheet instance. 第二个调用不能匹配工作表实例。 How can I achieve this? 我该如何实现?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using System.Timers;

namespace Ventron.VRange
{
    public class TestClass
    {
        private static List<OuterWorksheet> sheetList = new List<OuterWorksheet>();

        public static void run(Range range)
        {
            TestClass.sheetList.Add(new OuterWorksheet(range.Worksheet));
            TestClass.getWorkSheet(range.Worksheet);

            ElapsedEventHandler delayedFn = delegate(object sender, ElapsedEventArgs e)
            {
                System.Timers.Timer theTimer = (System.Timers.Timer)sender;
                if (theTimer.Enabled)
                {
                    theTimer.Stop();
                    theTimer.Enabled = false;
                    theTimer.Dispose();
                    theTimer = null;
                    TestClass.getWorkSheet(range.Worksheet);
                }
            };

            System.Timers.Timer timerInstance = new System.Timers.Timer(1);
            timerInstance.Elapsed += new System.Timers.ElapsedEventHandler(delayedFn);
            timerInstance.Interval = 1;
            timerInstance.Enabled = true;
        }

        internal static OuterWorksheet getWorkSheet(Worksheet worksheet)
        {
            System.Diagnostics.Debug.Write("*****************************\n");
            System.Diagnostics.Debug.Write(worksheet.CodeName + "\n");

            foreach (OuterWorksheet outerWS in TestClass.sheetList)
            {
                System.Diagnostics.Debug.Write(outerWS.worksheet.CodeName + "\n");
                if (outerWS.worksheet.Equals(worksheet))
                {
                    System.Diagnostics.Debug.Write("Worksheets are equal\n");
                    return outerWS;
                } else
                    System.Diagnostics.Debug.Write("Worksheets are not equal\n");
            }
            return null;
        }

        internal class OuterWorksheet
        {
            public Worksheet worksheet { get; private set; }
            public OuterWorksheet(Worksheet worksheet)
            {
                this.worksheet = worksheet;
            }
        }
    }
}

Output is: 输出为:

*****************************
Sheet5
Sheet5
Worksheets are equal

*****************************
Sheet5
Sheet5
Worksheets are not equal

Thx! 谢谢!

Each time you are getting a worksheet, it is generating a new wrapper instance around the COM object that is exposed by excel, so they are never equal by reference. 每次获取工作表时,它都会围绕由Excel公开的COM对象生成一个新的包装实例,因此,按引用它们永远不会相等。 Excel requires unique sheet names, so just compare the names when you are checking for equality. Excel需要唯一的工作表名称,因此在检查是否相等时只需比较名称即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM