Иногда я получаю следующее сообщение об ошибке при получении сериализованного массива с текущей версией MPI (v1.4):
Unhandled exception: System.Runtime.Serialization.SerializationException: The end of the stream was reached before processing was completed.
at System.Runtime.Serialization.Formatters.Binary .__ BinaryParser.Run ()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize (HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at MPI.BinaryFormatterSerializer.Deserialize [T] (Stream stream)
at MPI.Serialization.ReceiveLarge [T] (Communicator comm, Int32 source, Int32 tag, T & value, CompletedStatus & status)
at MPI.Communicator.Receive [T] (Int32 source, Int32 tag, T & value, CompletedStatus & status)
at MPI.Communicator.Receive [T] (Int32 source, Int32 tag, T & value)
at MPI.Communicator.Receive [T] (Int32 source, Int32 tag)
Спорадически означает, что ошибка всегда содержит блок получения моего кода в строка кода "SendList receiveList = comm.Receive (0, 2);" но всегда происходит в разное время. Иногда MPI удается передать 50% данных, иногда только 30% или только 10%. Я тестировал свою программу на разных компьютерах, но ошибка всегда одинакова. Все работало со старой версией MPI (v1.0). Мне пришлось обновиться до новой версии, потому что только с этим возможна отладка x64 в Visual Studio 2019 (со старой версией MPI отладка x64 всегда останавливается).
Угадай: Из-за сообщение об ошибке, это должно быть как-то связано с десериализацией данных. На мой взгляд, данные не были полностью переданы. Для других данных (меньшего размера и разных типов), которые я отправляю без сериализации через MPI (не показано в коде ниже), нет ошибки.
Вопрос: Как я могу решить проблему или обойти это?
Коротко обо мне: Извините за плохой английский sh, я использовал переводчик Google, я не обученный программист, и, следовательно, мне не хватает базовых знаний. Я бы сам отнесся к себе как к начинающему, который немного чему-то научил.
Вот мой код для отправки:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization;
namespace Calculator.Helper
{
public static class MPISender
{
public static void SendPolygonParts(ICommunicator comm, Polygon[] polygonParts, int i, bool isLast)
{
SendList sendObject = new SendList(polygonParts, isLast);
try
{
if (i != 0)
comm.Send(sendObject, i - 1, 2);
else
comm.Send(sendObject, 0, 2);
}
catch (SerializationException se)
{
if (i != 0)
Logger.Error(string.Format(CultureInfo.CurrentCulture, "Senden des Polygonpaketes Nr. {0} an Node/Soket/Core {1} nicht erfolgreich.", i, i - 1));
else if (i == 0 && polygonParts.Length == 0)
Logger.Error(string.Format(CultureInfo.CurrentCulture, "Senden des leeren Polygonpaketes von der Node/Soket/Core {0} ({2}) an die Hauptnode war nicht erfolgreich. Fehler: {1}", comm.Rank, se, comm.ProcessorName));
else if (i == 0 && polygonParts.Length != 0)
Logger.Error(string.Format(CultureInfo.CurrentCulture, "Senden des durch die Locherkennung analysierten Polygonpaketes mit {1} Polygonen von der Node/Soket/Core {0} ({2}) an die Hauptnode war nicht erfolgreich.", comm.Rank, polygonParts.Length, comm.ProcessorName));
}
}
}
}
using System;
namespace Calculator.MpiCommunication
{
[Serializable]
public class SendList
{
public bool IsLast { get; private set; }
private Polygon[] polygonList;
public Polygon[] GetPolygonList()
{
return polygonList;
}
private void SetPolygonList(Polygon[] value)
{
polygonList = value;
}
public SendList(Polygon[] liste, bool isLast)
{
SetPolygonList(liste);
IsLast = isLast;
}
}
}
Вот мой код получить:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Calculator
{
internal static class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool AttachConsole(int ProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool AllocConsole();
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeConsole();
}
static class Program
{
[STAThread]
static void Main(string[] args)
{
using (new MpiEnvironment(ref args))
{
ICommunicator comm = MpiEnvironment.Communicator;
if (comm.Rank == 0)
{
more code.......
}
else
{
while (comm.Receive<int>(0, 0) == 0)
{
Polygon[] polygons = Array.Empty<Polygon>();
bool isNotLast = true;
while (isNotLast)
{
SendList receivedList = comm.Receive<SendList>(0, 2);
List<Polygon> polygonsList = polygons == null ? new List<Polygon>() : polygons.ToList();
polygonsList.AddRange(receivedList.GetPolygonList());
isNotLast = !receivedList.IsLast;
polygons = polygonsList.ToArray();
}
more code....
break; // beende die while-schleife
}
Application.Exit();
}
}
}
}
}
Надеюсь, я предоставил всю необходимую информацию. Пожалуйста, помогите мне, я не знаю, что делать дальше.
Спасибо.