Несколько потоков, обращающихся к UniData из UniObjects.NET, выдают ошибку UNI RPC - PullRequest
1 голос
/ 01 декабря 2011

Мы использовали UniObjects.NET без проблем, пока не начали использовать его с BizTalk, который является многопоточным продуктом.Проблема заключается в ошибке ниже.Эта ошибка возникает только во 2-м потоке (и, возможно, в 3-м, 4-м и т. Д.).1-й поток подключается и может получать данные из UniData очень хорошо.Ошибка не говорит о многом, и поиск возвращает только один результат, не имеющий отношения к нашей конкретной проблеме.У кого-нибудь есть ответчик или он может указать мне правильное направление?Эта ошибка не включает пул подключений, и мы не используем пул подключений, поскольку это приводит к возникновению других ошибок.

Еще одна вещь, на которую следует обратить внимание, это то, что во время отладки мы написали некоторый код, который каждый поток записывал бы в отдельный поток.подайте некоторую отладочную информацию.Сам процесс записи отладочной информации в файл заставил оба потока работать правильно.Я не верю, что это проблема синхронизации соединения (то есть одновременное открытие UniSession), так как он завершается неудачно только в момент одновременного доступа к файлу UniData (при условии, что в то же время).

Документ UniObjects.NET для используемой нами версии файла 2.2.3.7377 (май 2010 г.) UniObjects.NET.Версия UniData - 7.2.

ОБНОВЛЕНИЕ: Также пытались с UniObjects.NET версии 2.2.5.7463, и это все еще вызывает то же исключение.

Inner exception: GetX - Error with file 'MYFILEX'. [IBM U2][UODOTNET - UNIRPC][ErrorCode=81004] An argument was requested from the RPC that was of an invalid type

Exception type: Exception
Source: MyBusinessObjects
Target Site: System.Collections.Generic.List`1[MyBusinessObjects.XResponse] GetX(System.Collections.Generic.List`1[MyBusinessObjects.Lookup])
The following is a stack trace that identifies the location where the exception occured
  at MyBusinessObjects.Lookups.GetX(List`1 Lookups)
  at MyBusinessObjects.Integration.GetXResponses(XmlDocument xml, String header, String gheader)
  at Orchestrations.XProcess.segment1(StopConditions stopOn)
  at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

ОБНОВЛЕНИЕ: Та же ошибка при чтении списков.

Inner exception: [IBM U2][UODOTNET - UNIRPC][ErrorCode=81004] An argument was requested from the RPC that was of an invalid type

Exception type: UniRPCPacketException
Source: 
UniRPCPacket Class
Target Site: Byte[] ReadByteArray(Int32)
The following is a stack trace that identifies the location where the exception occured

   at IBMU2.UODOTNET.UniRPCPMessage.ReadByteArray(Int32 anIndex)
   at IBMU2.UODOTNET.UniSelectList.ReadList()
   at IBMU2.UODOTNET.UniSelectList.ReadListAsStringArray()
   at MyBusinessObjects.Lookups.GetY()
   at MyBusinessObjects.Integration.GetResponses(XmlDocument xml, String header, String gsheader)
   at Orchestrations.Process.segment1(StopConditions stopOn)
   at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

1 Ответ

0 голосов
/ 25 мая 2012

Эта проблема решена.Теперь вы можете использовать последнюю версию UO.NET, и я надеюсь, что эта проблема решена.Вы также можете использовать новый программный продукт Rocket под названием «U2 Toolkit for .NET».Это интегрированное решение, содержащее функции ADO.NET, UO.NET и LINQ to Entity.Чтобы протестировать многопоточность, вы можете использовать следующий код (вместо BiZtalk Server).Мы использовали PLINQ и U2 Toolkit для .NET.

class Program
{
    static int NumberofThreads = 20;
    const string uniFileName = "PRODUCTS";
    static UniFile file = null;
    static UniSession session = GetUniSession();
    // setup ok/error counters
    static int ok = 0;
    static int error = 0;
    static void Main(string[] args)
    {
        // connect with no locks
        session.BlockingStrategy = UniObjectsTokens.UVT_WAIT_LOCKED;
        session.LockStrategy = UniObjectsTokens.UVT_NO_LOCKS;
        session.ReleaseStrategy = UniObjectsTokens.UVT_WRITE_RELEASE;
        Stopwatch watch = new Stopwatch();
        watch.Start();
        // take only 20 distinct record ids
        List<string> recordIds = new List<string>(RecordIds());
        // run as parallel
        Parallel.ForEach(recordIds, x =>
        {
            try
            {
                // connect to UniData CM file
                var file2 = session.CreateUniFile(uniFileName);
                // read individual record id
                file2.Read(x);
                file2.Close();
                Interlocked.Increment(ref ok);
                Console.WriteLine("rec id:" + x);
            }
            catch (Exception ex)
            {
                Interlocked.Increment(ref error);
                Console.WriteLine("Claim: {0}. Error: {1}", x, ex.Message);
            }
        });
        // set count & setup threads
        int count = 0;
        watch.Stop();
        // write error
        Console.WriteLine("Time: {2}, Count: {3}, OK: {0}, Error: {1}", ok, error, watch.Elapsed, count);
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
    static UniSession GetUniSession()
    {
        U2ConnectionStringBuilder conn_str = new U2ConnectionStringBuilder();
        conn_str.UserID = "user";
        conn_str.Password = "pass";
        conn_str.Server = "localhost";
        conn_str.Database = "XDEMO";
        conn_str.ServerType = "UNIDATA";
        conn_str.AccessMode = "Native";   // FOR UO
        conn_str.RpcServiceType = "udcs"; // FOR UO
        conn_str.Pooling = false;
        string s = conn_str.ToString();
        U2Connection con = new U2Connection();
        con.ConnectionString = s;
        con.Open();
        Console.WriteLine("Connected.........................");
        U2.Data.Client.UO.UniSession us1 = con.UniSession;
        if (file == null)
        {
            file = us1.CreateUniFile(uniFileName);
        }
        return us1;
    }

    public static List<string> RecordIds()
    {
        List<string> lRECIDList = new List<string>();
        UniSelectList sl = session.CreateUniSelectList(2);

        // Select UniFile
        UniFile fl = session.CreateUniFile("PRODUCTS");
        sl.Select(fl);

        bool lLastRecord = sl.LastRecordRead;
        int lIndex = 0;
        while (!lLastRecord)
        {
            string s4 = sl.Next();
            lRECIDList.Add(s4);
            //Console.WriteLine("Record ID:" + s4);
            lLastRecord = sl.LastRecordRead;
            lIndex++;
            if (lIndex >= NumberofThreads)
            {
                break;
            }
        }
        return lRECIDList;

    }
}
...