C# .NET应用程序在Lotus Notes会话打开时随机失败
我们创建了一个从IBM(Lotus)Notes收集数据的.NET应用程序。它通过COM对象(Lotus Domino对象)连接到Notes 一般来说,它可以工作并完成我们需要的所有操作,但在工作了几个小时后,应用程序停止工作。我的意思是,它有点冻结,停止做任何工作。它在不可预测的时间内发生在不同的数据库上,所以我找不到任何规律性 我们从应用程序获得的最后一条日志消息: System.Runtime.InteropServices.COMException(0x80010105):创建 具有CLSID的COM组件的实例 来自IClassFactory的{29131539-2EED-1069-BF5D-00DD011186B7}失败 由于以下错误:80010105服务器引发异常。 (来自HRESULT的异常:0x80010105(RPC_E_SERVERFAULT))。在 System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔值 publicOnly、Boolean noCheck、Boolean&canBeCached、, RuntimeMethodHandleInternal&ctor、Boolean&bNeedSecurityCheck)位于 System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔型 skipCheckThis、布尔填充缓存、堆栈爬网标记和堆栈标记)位于 位于的System.Activator.CreateInstance(类型,布尔非公共) 位于的System.Activator.CreateInstance(类型) 中的MyMethod(NotesServerConfig NotesServerConfig,字符串邮箱) D:…\MyClass.cs:第164行 或 System.Runtime.InteropServices.COMException(0x80040FA1):异常 来自Domino.ISession.Initialize(字符串)处的HRESULT:0x80040FA1 在MyMethod(NotesServerConfig NotesServerConfig,字符串 邮箱)在D:…\MyClass.cs:第164行 它们都链接到MyClass的第164行,这只是会话构造函数的调用:C# .NET应用程序在Lotus Notes会话打开时随机失败,c#,.net,com,lotus-notes,lotus,C#,.net,Com,Lotus Notes,Lotus,我们创建了一个从IBM(Lotus)Notes收集数据的.NET应用程序。它通过COM对象(Lotus Domino对象)连接到Notes 一般来说,它可以工作并完成我们需要的所有操作,但在工作了几个小时后,应用程序停止工作。我的意思是,它有点冻结,停止做任何工作。它在不可预测的时间内发生在不同的数据库上,所以我找不到任何规律性 我们从应用程序获得的最后一条日志消息: System.Runtime.InteropServices.COMException(0x80010105):创建 具有CLS
var session = new NotesSession();
我的real应用程序通过Topshelf作为Windows服务工作,因此其中有很多代码,因为该项目已经相当大了。因此,让我试着在这里放一个简化版本,不需要任何额外的代码和第三方库来展示我如何使用Lotus Domino对象:
using Domino;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace LotusTest
{
class Program
{
private const int _maxClientReCreateAttempts = 10;
private const string _password = "qwerty";
private const string _server = "test.server.ru";
private static readonly List<string> _dbNames = new List<string>
{
"mail\\test1", "mail\\test2", "mail\\test3"
};
static void Main(string[] args)
{
foreach (var dbName in _dbNames)
{
var folders = GetFolders(dbName);
foreach (var folder in folders)
{
var mailSubjects = GetEmailSubjects(folder, dbName);
foreach (var mailSubject in mailSubjects)
{
Console.WriteLine($"Mail {mailSubject} in {folder}, db: {dbName}");
}
}
}
}
private static List<string> GetFolders(string dbName)
{
var result = new List<string>();
var session = new NotesSession();
session.Initialize(_password);
var db = session.GetDatabase(_server, dbName, false);
if (db == null)
{
Console.WriteLine($"Can't read the database: {dbName}");
return result;
}
foreach (var view in db.Views)
{
if (!view.IsFolder) { continue; }
result.Add(view.Name);
}
return result;
}
private static List<string> GetEmailSubjects(string viewName, string dbName)
{
var result = new List<string>();
var session = new NotesSession();
session.Initialize(_password);
var db = session.GetDatabase(_server, dbName, false);
if (db == null)
{
Console.WriteLine($"Can't read the database: {dbName}");
return result;
}
var cv = db.GetView(viewName);
if (cv == null)
{
Console.WriteLine($"Can't read '{viewName}' folder of '{dbName}' database");
return result;
}
return ReadFolder(cv, session, dbName, viewName);
}
private static List<string> ReadFolder(NotesView cv, NotesSession session, string folder, string mailBox)
{
var result = new List<string>();
var doc = cv.GetFirstDocument();
int i = 0;
int errCount = 0;
bool lastGetWithError = false;
int totalAmount = cv?.AllEntries?.Count ?? 0;
int clientReCreateAttempts = 0;
while (doc != null)
{
try
{
if (!lastGetWithError)
{
result.Add(doc.GetItemValue("Subject")[0]);
Console.WriteLine($"Folder: {folder}, processed: {i + 1 - errCount} of {totalAmount}");
}
doc = cv.GetNextDocument(doc);
lastGetWithError = false;
}
catch (COMException ex)
{
Console.WriteLine($"Error on reading folder {folder} of mailbox {mailBox}.\r\n{ex}");
if (clientReCreateAttempts > _maxClientReCreateAttempts)
{
throw new Exception("Reading mail doc error: ", ex);
}
Console.WriteLine($"Trying to re-create Notes session");
session = new NotesSession();
clientReCreateAttempts++;
}
catch (Exception ex)
{
Console.WriteLine($"Error on reading folder {folder} of mailbox {mailBox}.\r\n{ex}");
lastGetWithError = true;
}
finally
{
i++;
}
}
return result;
}
}
}
使用Domino;
使用制度;
使用System.Collections.Generic;
使用System.Runtime.InteropServices;
名称空间LotusTest
{
班级计划
{
私有常量int_maxclientre=10;
私有常量字符串\u password=“qwerty”;
私有常量字符串_server=“test.server.ru”;
私有静态只读列表_dbNames=新列表
{
“邮件\\test1”、“邮件\\test2”、“邮件\\test3”
};
静态void Main(字符串[]参数)
{
foreach(变量dbName在_dbNames中)
{
var folders=GetFolders(dbName);
foreach(文件夹中的var文件夹)
{
var mailSubjects=GetEmailSubjects(文件夹,数据库名);
foreach(mailSubjects中的var mailSubject)
{
WriteLine($“邮件{mailSubject}位于{folder},db:{dbName}”)中;
}
}
}
}
私有静态列表GetFolders(字符串dbName)
{
var result=新列表();
var session=newnotessession();
会话初始化(_密码);
var db=session.GetDatabase(_server,dbName,false);
if(db==null)
{
WriteLine($“无法读取数据库:{dbName}”);
返回结果;
}
foreach(db.Views中的变量视图)
{
如果(!view.IsFolder){continue;}
结果.添加(视图.名称);
}
返回结果;
}
私有静态列表GetEmailSubjects(字符串viewName、字符串dbName)
{
var result=新列表();
var session=newnotessession();
会话初始化(_密码);
var db=session.GetDatabase(_server,dbName,false);
if(db==null)
{
WriteLine($“无法读取数据库:{dbName}”);
返回结果;
}
var cv=db.GetView(viewName);
如果(cv==null)
{
WriteLine($“无法读取“{dbName}”数据库的“{viewName}”文件夹”);
返回结果;
}
返回ReadFolder(cv、会话、数据库名、视图名);
}
私有静态列表读取文件夹(NotesView cv、NotesSession会话、字符串文件夹、字符串邮箱)
{
var result=新列表();
var doc=cv.GetFirstDocument();
int i=0;
int errCount=0;
bool lastGetWithError=false;
int totalAmount=cv?.AllEntries?.Count±0;
int clientre=0;
while(doc!=null)
{
尝试
{
如果(!lastGetWithError)
{
结果.添加(doc.GetItemValue(“主题”)[0]);
WriteLine($“文件夹:{Folder},已处理:{i+1-errCount},共{totalAmount}”);
}
doc=cv.GetNextDocument(doc);
lastGetWithError=false;
}
捕获(COMException ex)
{
Console.WriteLine($”读取邮箱{mailbox}的文件夹{folder}时出错。\r\n{ex}”);
如果(clientReCreateAttempts>\u maxClientReCreateAttempts)
{
抛出新异常(“读取邮件文档错误:”,ex);
}
Console.WriteLine($“正在尝试重新创建Notes会话”);
会话=新的NotesSession();
clientre++;
}
捕获(例外情况除外)
{
Console.WriteLine($”读取邮箱{mailbox}的文件夹{folder}时出错。\r\n{ex}”);