EventStore duplicate commit exception - c#

UPDATE:
We are getting getting System.Data.SqlClient.SqlException. The message is:
Violation of PRIMARY KEY constraint 'PK_Commits'. Cannot insert duplicate key in object 'dbo.Commits'.\r\nThe statement has been terminated
It seems like EventStore is using streamid and commitid as unique id.
We use event store to append events as below.
public bool TryAppend(object[] content)
{
if (content == null)
throw new ArgumentNullException("content");
try
{
using (var stream = m_storage.OpenStream(m_streamID, 0, int.MaxValue))
{
var versionInStore = stream.StreamRevision;
content.ToList().ForEach(m =>
{
var version = ++versionInStore;
var key = string.Format("{0}-{1:00000000}", m.GetType().Name, version);
var savedMessage = new SavedRecord(key, version, m);
stream.Add(new EventMessage { Body = savedMessage });
});
stream.CommitChanges(Guid.NewGuid());
}
return true;
}
catch (Exception e)
{
m_logger.LogError(e);
return false;
}
}
The configuration of EventStore is as below. We are using Sql Serer 2008 as persistance store.
return Wireup.Init()
.LogToOutputWindow()
.UsingSqlPersistence(m_connectionName)
.WithDialect(new MsSqlDialect())
.EnlistInAmbientTransaction() // two-phase commit
.InitializeStorageEngine()
.UsingJsonSerialization()
.Compress()
.UsingSynchronousDispatchScheduler()
.DispatchTo(new DelegateMessageDispatcher(DispatchCommit))
.Build();
Any ideas why are gettin the dupplicate commit exception?
Thanks

Have got the same issue; in my case it was probably because of different threads was adding different events to the stream with same id at the same time.
Have writtent the following code to be able to retry adding events:
private void TryAddEvent(IStoreEvents storeEvents, IUserEvent anEvent, Guid streamId)
{
var isCommitSuccessful = false;
for (var i = 0; i < 10 && !isCommitSuccessful; i++)
{
try
{
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
stream.Add(new EventMessage {Body = anEvent});
if (stream.UncommittedEvents.All(e => e.Body != anEvent))
{
stream.Add(new EventMessage {Body = anEvent});
}
stream.CommitChanges(Guid.NewGuid());
}
isCommitSuccessful = true;
}
catch (Exception ex)
{
if (!(ex is SqlException) && !(ex is ConcurrencyException))
{
throw;
}
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
if (stream.CommittedEvents.Any(e => e.Body == anEvent))
{
isCommitSuccessful = true;
}
}
}
}
if (!isCommitSuccessful)
{
throw new ConcurrencyException(String.Format("Cannot add {0} to event store", anEvent.GetType()));
}
}
Hope it would help.

Related

Creating a folder under Inbox using Mocrosoft.Graph 2.0.14

I'm trying to create a folder under my Inbox in Office 365 using MS Graph 2.0, but I'm finding surprisingly little information on the topic anywhere on the internet. The authentication works fine, and I was able to read the existing test folder. My method for doing this is below:
private void SetupMailBoxes()
{
SmartLog.EnterMethod("SetupMailBoxes()");
MailFolder inbox = null;
try
{
bool dbErrorFolder = false;
bool exchangeErrorFolder = false;
inbox = _journalMailbox.MailFolders.Inbox.Request().GetAsync().GetAwaiter().GetResult();
if (inbox.ChildFolderCount > 0)
{
inbox.ChildFolders = _journalMailbox.MailFolders.Inbox.ChildFolders.Request().GetAsync().GetAwaiter().GetResult();
}
if (inbox.ChildFolders != null)
{
for (int i = 0; i < inbox.ChildFolders.Count && (!dbErrorFolder || !exchangeErrorFolder); i++)
{
if (inbox.ChildFolders[i].DisplayName.ToLower() == "db-error-items")
{
dbErrorFolder = true;
}
else if (inbox.ChildFolders[i].DisplayName.ToLower() == "exchange-error-items")
{
exchangeErrorFolder = true;
}
}
}
if (!dbErrorFolder)
{
try
{
//inbox.ODataType = "post";
var folder = _journalMailbox.MailFolders.Inbox.Request().CreateAsync(
new MailFolder()
{
DisplayName = "DB-Error_Items",
}).GetAwaiter().GetResult();
//inbox.ChildFolders.Add(folder);
}
catch (Exception ex)
{
throw;
}
}
}
catch (Exception exp)
{
SmartLog.LeaveMethod("SetupMailBoxes()");
throw;
}
finally
{
}
SmartLog.LeaveMethod("SetupMailBoxes()");
}
Where _clientSecretCredential is created like this:
_graphServiceClient = null;
_options = new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud };
_clientSecretCredential = new ClientSecretCredential(
this.FindString(config.TenentID)
, this.FindString(config.AppID)
, this.FindString(config.Secret)
, _options);
string[] apiScope = new string[] { this.FindString(config.Scope) };
_token = _clientSecretCredential.GetToken(new Azure.Core.TokenRequestContext(apiScope));
graphServiceClient = new GraphServiceClient(_clientSecretCredential, apiScope);
IUserRequestBuilder _journalMailbox = _graphServiceClient.Users["journal#mycompany.com"];
The code seems correct, but everytime I execute "_journalMailbox.MailFolders.Inbox.Request().CreateAsync", I get the following error:
Code: ErrorInvalidRequest
Message: The OData request is not supported.
ClientRequestId:Some Guid.
From what I could figure out by searching on the internet, it has to do with the method using the wrong method to access the API. I mean like, its using "GET" in stead of "POST" or something like that, but that would mean its a bug in the MS code, and that would an unimaginably big oversight on Microsoft's part, so I can't think its that.
I've tried searching documentation on how to create subfolders, but of the preciously few results I'm getting, almost none has C# code samples, and of those, all are of the previous version of Microsoft Graph.
I'm really stumped here, I'm amazed at how hard it is to find any documentation to do something that is supposed to be simple and straight forward.
Ok, so it turned out that I was blind again. Here is the correct code for what I was trying to do:
private void SetupMailBoxes()
{
SmartLog.EnterMethod("SetupMailBoxes()");
MailFolder inbox = null;
try
{
bool dbErrorFolder = false;
bool exchangeErrorFolder = false;
inbox = _journalMailbox.MailFolders.Inbox.Request().GetAsync().GetAwaiter().GetResult();
if (inbox.ChildFolderCount > 0)
{
inbox.ChildFolders = _journalMailbox.MailFolders.Inbox.ChildFolders.Request().GetAsync().GetAwaiter().GetResult();
}
if (inbox.ChildFolders != null)
{
for (int i = 0; i < inbox.ChildFolders.Count && (!dbErrorFolder || !exchangeErrorFolder); i++)
{
if (inbox.ChildFolders[i].DisplayName.ToLower() == "db-error-items")
{
dbErrorFolder = true;
}
else if (inbox.ChildFolders[i].DisplayName.ToLower() == "exchange-error-items")
{
exchangeErrorFolder = true;
}
}
}
else
{
inbox.ChildFolders = new MailFolderChildFoldersCollectionPage();
}
if (!dbErrorFolder)
{
try
{
var folder = new MailFolder()
{
DisplayName = "DB-Error-Items",
IsHidden = false,
ParentFolderId = inbox.Id
};
folder = _journalMailbox.MailFolders[inbox.Id].ChildFolders.Request().AddAsync(folder).GetAwaiter().GetResult();
inbox.ChildFolders.Add(folder);
}
catch (Exception ex)
{
throw;
}
}
}
catch (Exception exp)
{
SmartLog.LeaveMethod("SetupMailBoxes()");
throw;
}
finally
{
}
SmartLog.LeaveMethod("SetupMailBoxes()");
}

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects duplicate objects

Hi I am using Entity Framework Code First, for my Database and CRUD operations, but when I am trying to add into couple of tables using entities.
Here is the message I am getting:
The relationship between the two objects cannot be defined because
they are attached to different ObjectContext objects duplicate objects
My create function is as below:
public T Create(T item)
{
try
{
if (ufb != null && ufb.CurrentUser != null)
{
SetValue("CreatedByUserId", item, ufb.CurrentUser.Id);
SetValue("UpdatedByUserId", item, ufb.CurrentUser.Id);
}
SetValue("DateCreated", item, DateTime.Now);
SetValue("DateUpdated", item, DateTime.Now);
var newEntry = this.DbSet.Add(item);
this.Context.Database.Log = message => LogHandler.LogInfo(1111, message);
try
{
this.Context.SaveChanges();
}
catch (Exception ex)
{
LogHandler.LogInfo(2501, ex.Message);
}
BuildMetaData(item, true, true);
return newEntry;
}
catch (DbEntityValidationException dbEx)
{
// http://forums.asp.net/t/2014382.aspx?Validation+failed+for+one+or+more+entities+See+EntityValidationErrors+property+for+more+details+
string msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
msg += validationError.PropertyName;
msg += "---";
msg += validationError.ErrorMessage;
msg += "||";
}
}
throw new Exception("7777 CREATE EntityValidationErrors: " + msg);
}
}
Here is how I am trying to call the create method for couple of Entities, can somebody please suggest me what am I doing wrong, any help please
public InspectionItem Create(InspectionItem inspectionItem)
{
try
{
//------------------------------------------------------
// save the indexes to the multiple categories,
// then clear the list of category objects in the
//------------------------------------------------------
List<int> inspectionCategoryIdlist = new List<int>();
foreach (var itemCat in inspectionItem.InspectionItemCategory)
{
int itemCatId = itemCat.ViolationTypeId;
inspectionCategoryIdlist.Add(itemCatId);
}
inspectionItem.InspectionItemCategory.Clear();
inspectionItem.InspectionItemNumber = "TEMP"; // just get past the Create
var saveInspectionItemCategories = inspectionItem.InspectionItemCategory;
inspectionItem.InspectionItemNumber = CalculateInspectionItemNumber(inspectionItem.InspectionItemId);
UnitOfWork.InspectionItemRepository.Create(inspectionItem);
if ((inspectionItem != null) && (inspectionItem.InspectionItemId != null) && (inspectionItem.InspectionItemId > 0))
foreach (var violationTypeId in inspectionCategoryIdlist)
{
var a = new InspectionItemViolationCategory();
a.InspectionItem = inspectionItem;
var violationType = new ViolationType();
violationType = UnitOfWork.ViolationTypeRepository.Find(violationTypeId);
a.ViolationType = violationType;
UnitOfWork.InspectionItemViolationCategoryRepository.Create(a);
}
return inspectionItem;
}
catch (Exception ex)
{
LogHandler.LogError(2101, "Commit Fail in Inspection Item Create", ex);
throw ex;
}
}
Any suggestion or code sample anything helps, thanks a lot.

how to call Call Async Methods in Parallel.ForEach loop properly [duplicate]

This question already has answers here:
Nesting await in Parallel.ForEach [duplicate]
(11 answers)
Closed 2 years ago.
how to call Call Async Methods in Parallel.ForEach loop properly.billDataService.SaveBillDetail and GetProfileDetails both are async methods.data saving in MongoDB in SaveBillDetail .
public async Task ConvertXMLFileToJSON()
{
try
{
if (Directory.Exists(_appSettings.DocumentsStorage))
{
int i = 1; //Test
bool exists = Directory.GetFiles(_appSettings.DocumentsStorage).Any(x => x.Equals(Path.Combine(_appSettings.DocumentsStorage, "Ready.txt"), StringComparison.OrdinalIgnoreCase)); //Need to check
if (exists)
{
Parallel.ForEach(System.IO.Directory.GetFiles(_appSettings.DocumentsStorage, "*.xml"), (currentFile) =>
{
try
{
XElement root = XElement.Load(currentFile); // or .Parse(string);
//Removing CDATA property from XElement.
XElement items = XElement.Parse(root.ToString().Replace("<![CDATA", "").Replace("]]>", "").Replace("[", ""));
//Removing XML_INFO Tag from XElement.
items.Elements("XML_INFO").Remove();
XmlDocument xmlDoc = new XmlDocument();
using (XmlReader xmlReader = items.CreateReader())
{
xmlDoc.Load(xmlReader);
}
var json = JsonConvert.SerializeXmlNode(xmlDoc);
billDetails obj = JsonConvert.DeserializeObject<billDetails>(json);
BillDetails billDetails = new BillDetails();
billDetails.AccountNumber = obj.BILL_INFO.BILL_RUN.ACCT_INFO.ACCT_CODE;
billDetails.MobileNumber = obj.BILL_INFO.BILL_RUN.ACCT_INFO.PRINCIPAL_NO.STR_PRINCIPAL_NO;
billDetails.BillDate = DateTime.ParseExact(obj.BILL_INFO.BILL_RUN.BILL_PROP.TO_DATE, "dd/MM/yyyy", CultureInfo.InvariantCulture);
billDetails.DueAmount = obj.BILL_INFO.BILL_RUN.ACCT_INFO.ACCT_BALANCE_TRACE.TOTAL_DUE;
billDetails.CustomerName = obj.BILL_INFO.BILL_RUN.CUST_INFO.CUST_NAME.FULL_NAME;
billDetails.InvoiceId = obj.BILL_INFO.BILL_RUN.BILL_PROP.INVOICE_ID;
billDetails.DueDate = DateTime.ParseExact(obj.BILL_INFO.BILL_RUN.BILL_PROP.DUE_DATE, "yyyyMMdd hh:mm:ss", CultureInfo.InvariantCulture);
billDetails.RepositoryName = "postpaid";
billDetails.BillRun = obj.BILL_INFO.BILL_RUN; //tempObj2.BILL_INFO.ToString().Remove(0, 1);
billDetails.ObjectId = Guid.NewGuid().ToString();
if (billDetails != null)
{
BillDataService billDataService = new BillDataService(_dbConfig);
Console.WriteLine("SaveBillDetail");
if (billDataService.SaveBillDetail(billDetails) != null)
{
Console.WriteLine("SaveBillDetail done");
GetProfileDetails(billDetails);
_logger?.LogInformation(i++ + " File Success");
Console.WriteLine(i++ + " File Success");
// File.Delete(file); //Delete File
}
}
}
catch (Exception ex)
{
_logger?.LogError(ex, "Error");
}
finally { }
});
}
}
}
catch (Exception ex)
{
_logger?.LogError(ex, "Error");
}
finally
{
}
}
public async Task GetProfileDetails(BillDetails billDetails)
{
try
{
ProfileService profileService = new ProfileService(_dbConfig);
var searchFilter = new SearchFilter
{
Filters = new List<Filter>()
};
if (!string.IsNullOrEmpty(billDetails.AccountNumber))
{
searchFilter.Filters.Add(new Filter() { PropertyName = "AccountNumber", Operator = Operator.Equals, Value = billDetails.AccountNumber, CaseSensitive = true });
}
if (searchFilter != null)
{
Profile profile = await profileService.GetProfiles(searchFilter);
if (profile != null)
{
await SendMailNotification(profile, billDetails);
}
else
{
_logger?.LogError("Profile Info not found");
}
}
}
catch (Exception ex)
{
_logger?.LogError(ex, "Error");
throw;
}
finally { }
}
normal for each loop I can able to call and save data in MongoDB.but Parallel.ForEach loop I cannot able to call the async method using await and data saving in mongo also not working.inside Parallel.ForEach loop I avoided using await of the front of the calling method.
You can change your code to be like below and wait for all the tasks to be completed.
var fileTasks = System.IO.Directory.GetFiles(_appSettings.DocumentsStorage, "*.xml").Select(async currentFile =>
{
try
{
XElement root = XElement.Load(currentFile); // or .Parse(string);
// rest o your code here
if (billDetails != null)
{
if (billDataService.SaveBillDetail(billDetails) != null)
{
Console.WriteLine("SaveBillDetail done");
await GetProfileDetails(billDetails);
}
}
}
catch(exception ex) { //log exeption }
});
await Task.WhenAll(fileTasks);

How to detect edited or deleted messages on telegram TLSharp

I am trying to detect which message is edited or deleted on a subscribed channel on telegram with TLSharp library in c#.
1- in a while(true) loop I am getting latest updates.
2- when I delete or edit a message for test, I receive TLUpdateChannelTooLong only.
3- then I use client.GetHistoryAsync function to get channel messages, and check their EditDate.
But I don't know how much should I go deep in history and I can not find deleted message with this code easily.
Is there any solution to find deleted/edited messages easy and safe?
Part of my code:
state = await client.SendRequestAsync<TLState>(new TLRequestGetState());
while (true)
{
await Task.Delay(1000);
var req = new TLRequestGetDifference() { Date = state.Date, Pts = state.Pts, Qts = state.Qts };
TLDifference diff = null;
try
{
diff = await client.SendRequestAsync<TLAbsDifference>(req) as TLDifference;
}
catch (Exception ex)
{
HandleThisException(ex);
}
//--
if (diff != null)
{
state = await client.SendRequestAsync<TLState>(new TLRequestGetState());
foreach (var upd in diff.OtherUpdates.OfType<TLUpdateNewChannelMessage>())
{
var tm = (upd.Message as TLMessage);
if (tm == null) { continue; } // ?
var textMessage = tm.Message;
if (tm.Media != null)
{
if (tm.Media.GetType().ToString() == "TeleSharp.TL.TLMessageMediaPhoto")
{
var tLMessageMediaPhoto = (tm.Media as TLMessageMediaPhoto);
textMessage = tLMessageMediaPhoto.Caption;
}
}
try
{
var from = (tm.ToId as TLPeerChannel).ChannelId;
long replyTo = tm.ReplyToMsgId == null ? 0 : (long)tm.ReplyToMsgId;
await AnalyzeNewMessage( ... );
}
catch (Exception exParsing)
{
HandleThisException(exParsing);
}
}
// Checking Edited/Deleted Messages
foreach(var upLong in diff.OtherUpdates.OfType<TLUpdateChannelTooLong>())
{
TLChannel theChat = null;
foreach(var chat in diff.Chats.OfType<TLChannel>())
{
if(chat.Id == upLong.ChannelId) { theChat = chat; break; }
}
if (theChat != null)
{
var x = await client.GetHistoryAsync(
new TLInputPeerChannel { ChannelId = theChat.Id, AccessHash = (long)theChat.AccessHash },
0,-1,2
); // checking only 2 last messages!
var ChMsgs = x as TLChannelMessages;
foreach (var msg in ChMsgs.Messages.OfType<TLMessage>())
{
if(msg.EditDate != null)
{
var txt = msg.Message;
if (msg.Media != null)
{
if (msg.Media.GetType().ToString() == "TeleSharp.TL.TLMessageMediaPhoto")
{
txt = (msg.Media as TLMessageMediaPhoto).Caption;
}
}
await AnalyzeEditedMessage( ... );
}
}
}
}
}
}

How to call a method in .cs file which was implemented in code behind?

I have a button click event in code behind file as follows:
protected void btnArchive_Click(object sender, EventArgs e)
{
try
{
if (projectId == 0)
{
return;
}
Int32 serverPathId = 0;
ProjectArchiveResponse archiveResponse;
if (!int.TryParse(this.ddlSourceServer.SelectedValue, out serverPathId))
return;
if (string.IsNullOrEmpty(hidFileCount.Value))
{
this.ShowMsg(this.divMessage, Resources.Resource.ProjectFileArchiveNotAllowed, MessageType.Failed);
//The project files couldn't be archived until archive operation was completed.
return;
}
ProjectManager projectManager = new ProjectManager(null, BasePage.GetCurrentUser(), null) { IsServiceCall = false};
try
{
archiveResponse = projectManager.StartProjectArchive(projectId, false, () =>
{
foreach (Control control in tdFileList.Controls.Cast<Control>())
{
if (control is Dell.AFP.UserControl.ProjectFileListBaseControl)
{
((ProjectFileListBaseControl)control).Refresh();
}
}
}, false);
if (archiveResponse.MassivePackageID > 0)
{
this.ViewState["transferPackageId"] = archiveResponse.MassivePackageID;
PopupMonitor(archiveResponse.MassivePackageID);
}
//handled for any erorrs while submitting massive package or any unhandled exceptions will be taken care here
if (archiveResponse._CustomError != null && !string.IsNullOrEmpty(archiveResponse._CustomError.Erorrmessage))
{
if (!archiveResponse._CustomError._Erorrtype.Equals(MessageType.Info))
logger.ErrorFormat("Error occurred with details : {0}", archiveResponse._CustomError.Erorrmessage);
ShowMsg(divMessage, archiveResponse._CustomError.Erorrmessage, (MessageType)archiveResponse._CustomError._Erorrtype);
}
}
catch (KnownErrorException ke)
{
//logger.Fatal("UnExpected exception occured. Exception Details " + ke.Message);
logger.Fatal(ke.Message);
if (ke.Error.Type.Equals(DELL.AFP.Management.Exceptions.ErrorType.Warning))
this.ShowMsg(this.divMessage, ke.Message, MessageType.Info);
else
this.ShowMsg(this.divMessage, ke.Message, MessageType.Failed);
}
catch (Exception ke)
{
logger.ErrorFormat("UnExpected exception has occured with details : {0} - {1}", ke.Message, ke.StackTrace);
//ShowMsg(divMessage, "UnExpected exception has occured. Details are logged. Please try after sometime", MessageType.Failed);
ShowMsg(divMessage,ke.Message, MessageType.Failed);
}
}
In this event I am calling a method StartProjectArchive which is in ProjectManager.cs file
StartProjectArchive method in ProjectManager.cs is as follows:
public ProjectArchiveResponse StartProjectArchive(int projectID, bool promoteAfterArchive, Action uiRefresh, bool waitTillTransfered, string archiveNotificationUrl = null)
{
ProjectArchiveResponse projectArchiveResponse = new ProjectArchiveResponse() { ProjectID = projectID, MassivePackageID = -1 };
string sourceServerPath = String.Empty;
int packageID =0;
Int32 sourceServerPathID = GetSourceServerPath(projectID, out sourceServerPath);
var filesWhichNeedsToBeArchived = GetFilesWhichNeedsToBeArchived(projectID, sourceServerPathID, uiRefresh);
if (objFilesNotInSourceServer != null && objFilesNotInSourceServer.Count > 0)
KnownErrorException.Throw("ePRJARCMISSFILE01", string.Join(",", objFilesNotInSourceServer.ToArray()));
if (filesWhichNeedsToBeArchived != null)
{
MassiveServiceClientProxy proxy = new MassiveServiceClientProxy();
Dictionary<string, string> files = new Dictionary<string, string>();
filesWhichNeedsToBeArchived.Select(file => new
{
SourcePath = file.FileName,
DestinationPath = Path.Combine(ConfigurationManager.AppSettings["ArchiveProcessPrefixFolder"],
Path.GetDirectoryName(file.FileName), Path.GetFileName(file.FileName),
projectFilelist.Where(pf => string.Compare(pf.FileName, file.FileName, true) == 0).First().VersionID.ToString(),
Path.GetFileName(file.FileName))
}).ToList().
ForEach(file =>
{
if (!files.ContainsKey(file.SourcePath))
files.Add(file.SourcePath, file.DestinationPath);
});
if (files.Count > 0)
{
string packageDescription = "AFP 4.0: " + projectID.ToString(),
targetServerGroupName = archiveServer.MassiveServerGroupName,
userSuppliedId = "AFP 4.0: " + EndUserInfo.UserName;
try
{
packageID = proxy.SubmitPackageWithDestinationPath(files, packageDescription, new[] { sourceServerPath },
targetServerGroupName, userSuppliedId, MassiveService.MassivePriority.URGENT, true);
}
catch (Exception ex)
{
if (IsServiceCall == true)
KnownErrorException.Throw("wPRJARCMASER01");
else
return new ProjectArchiveResponse() { _CustomError = new CustomError { _Erorrtype = Model.ErrorType.Failed, Erorrmessage = ex.Message } };
}
if (packageID > 0)
{
ProjectFileBizManager projectFileBM = new ProjectFileBizManager();
projectFileBM.InsertArchiveTransferPackageByProjectFileList(
GetProjectFileIDsByFileName(projectID, filesWhichNeedsToBeArchived.Select(file => file.FileName).ToArray()), filesWhichNeedsToBeArchived.Select(file => file.FileName).ToArray(), packageID, projectID, EndUserInfo.UserId);
TransferPackageBizManager transferPackageBM = new TransferPackageBizManager();
if (promoteAfterArchive)
{
transferPackageBM.UpdateTransferPackageFeature(packageID, promoteAfterArchive);
}
projectArchiveResponse.MassivePackageID = packageID;
if (waitTillTransfered)
{
Task<ProjectArchiveResponse> mainTask = Task<ProjectArchiveResponse>.Factory.StartNew(
() =>
{
Task<Enums.TransferStatusEnum> packageTransfer = Task<Enums.TransferStatusEnum>.Factory.StartNew(
() =>
{
try
{
TransferPackage transferPackage = null;
while (true)
{
transferPackage = transferPackageBM.GetTransferPackage(packageID);
if (transferPackage.TransferStatus.TransferStatusId == (int)Enums.TransferStatusEnum.Submitted || transferPackage.TransferStatus.TransferStatusId == (int)Enums.TransferStatusEnum.Transferring)
Thread.Sleep(8000);
else
break;
}
logger.DebugFormat("Massive package status : {0} for Package : {1}", (Enums.TransferStatusEnum)transferPackage.TransferStatus.TransferStatusId, transferPackage.TransferPackageId);
return (Enums.TransferStatusEnum)transferPackage.TransferStatus.TransferStatusId;
}
catch (Exception exp)
{
logger.ErrorFormat("Project Archive Error, while trying to find massive package status : {0}", exp);
return Enums.TransferStatusEnum.Submitted;
}
});
try
{
Int32 timeOutInMins = (ConfigurationManager.AppSettings["ProjectArchive_PackageMonitorTimeoutInMinutes"] == null) ? 60 :
Convert.ToInt32(ConfigurationManager.AppSettings["ProjectArchive_PackageMonitorTimeoutInMinutes"]);
if (!Task.WaitAll(new Task[] { packageTransfer }, timeOutInMins * 60 * 1000))
{
projectArchiveResponse.Timedout = true;
projectArchiveResponse.TransferStatus = Enums.TransferStatusEnum.Submitted;
}
else
projectArchiveResponse.TransferStatus = packageTransfer.Result;
logger.DebugFormat("Project Archive Response, Project ID: {0}\n Package ID : {1},\n IsTimedout : {2},\n Timeout value : {3} minutes, \n Transfer Status : {4}", projectArchiveResponse.ProjectID, projectArchiveResponse.MassivePackageID, projectArchiveResponse.Timedout, timeOutInMins, projectArchiveResponse.TransferStatus);
}
catch (Exception exp)
{
logger.ErrorFormat("Project Archive Error, while waiting to fetch massive package status : {0}", exp);
}
return projectArchiveResponse;
});
if (!string.IsNullOrEmpty(archiveNotificationUrl))
{
mainTask.ContinueWith((a) =>
{
try
{
AFPArchiveNotifyProxy archiveNotification = new AFPArchiveNotifyProxy();
ArchiveNotificationService.ProjectArchiveResponse archiveResponse = new ArchiveNotificationService.ProjectArchiveResponse()
{
MassivePackageID = a.Result.MassivePackageID,
ProjectID = a.Result.ProjectID,
IsTimedout = a.Result.Timedout,
ArchiveStatus = (Enum.Parse(typeof(ArchiveNotificationService.ArchiveStatusEnum), (a.Result.TransferStatus.ToString())) as ArchiveNotificationService.ArchiveStatusEnum?).Value
};
MassiveServiceClientProxy massiveServiceClientProxy = new MassiveServiceClientProxy();
FileTransferRequest[] fileTransferRequests = massiveServiceClientProxy.GetFileStatus(a.Result.MassivePackageID);
archiveResponse.Files = fileTransferRequests.Select(f => f.FileName).ToArray();
archiveNotification.ProjectArchiveUpdate(archiveNotificationUrl, archiveResponse);
logger.DebugFormat("Project Archive Response Notification, Project ID: {0}\n Package ID : {1},\n IsTimedout : {2},\n Archive Status :{3},\n Notification Url : {4},\n Total Files : {5}", archiveResponse.ProjectID, archiveResponse.MassivePackageID, archiveResponse.IsTimedout, archiveResponse.ArchiveStatus, archiveNotificationUrl, archiveResponse.Files.Count());
logger.DebugFormat("Package ID : {0}, Files : {1}", archiveResponse.MassivePackageID, string.Join(",", archiveResponse.Files.ToArray()));
}
catch (Exception exp)
{
logger.ErrorFormat("Project Archive Error, while invoking archive notification : {0}", exp);
}
});
projectArchiveResponse.TransferStatus = Enums.TransferStatusEnum.Submitted;
return projectArchiveResponse;
}
else
{
mainTask.Wait();
}
}
}
else
{
if (IsServiceCall == true)
KnownErrorException.Throw("ePRJARCMASS01");
else
return new ProjectArchiveResponse() { _CustomError = new CustomError { _Erorrtype = Model.ErrorType.Failed, Erorrmessage = "Massive has not returned the massive packageid" } };
}
}
else
{
// this.ShowMsg(this.divMessage, Resources.Resource.NoFilesToArchive, MessageType.Info);
if (IsServiceCall == true)
KnownErrorException.Throw("wPRJARCNOFILES01");
else
return new ProjectArchiveResponse() { _CustomError = new CustomError { _Erorrtype = Model.ErrorType.Info, Erorrmessage = "There are no files to archive" } };
}
}
return projectArchiveResponse;
}
In this we are taking a parameter as "Action uiRefresh" . we are calling this uiRefresh as method in GetFilesWhichNeedsToBeArchived which was in startArchiveProject method. This Refresh method in tunrn calls the method in code behind file. This was passed as a control when we are invoking startArchiveProject in code behind file. Now I have one more thing which I need to implement. I have a method Pop-Up files in code behind file. I need to call that in ProjectManager.cs class inside the Method GetFilesWhichNeedsTobeArchive. In that pop-up I will have a button and checkboxes. Upon the selection user I need to get the details from pop-up and then I have to continue with the remaining execution in ProjectManger.cs page.
Can someone help on this?
Assuming that you have a button named btnArchive then the add click event subscription, pointing to the method you have (which looks like click-event handle proc)
btnArchive.Click+=(s,e)=>btnArchive_Click(s,e);
Regards

Categories