我正在編寫一個使用Sync Framework v2.1與WCF Web服務組合的n層應用程序。我的代碼是基於這個例子:Database-Sync嘗試在Sync Framework中使用批處理進行同步時收到System.Error
同步功能似乎沒有問題的工作。但是,當我添加批處理功能時,我收到一個證明難以調試的錯誤。
在溶液(a WPF應用程序)的客戶機部分,我有從KnowledgeSyncProvider繼承的虛擬類。它也實現了IDisposable接口。我使用這個類來調用我編寫的WCF服務,並在那裏使用同步功能。當同步代碼運行時(orchestrator.Synchronize()被調用),一切似乎都正常工作,並且EndSession函數覆蓋了我編寫的運行時沒有錯誤。但是,在執行完該函數後,System.Error會從Microsoft.Synchronization.CoreInterop.ISyncSession.Start內發生(據我所知)。
我寫提供了IDisposable功能的功能從來不被稱爲那麼,事情是EndSession之後發生的事情,但我的應用程序的虛擬KnowledgeSyncProvider類可配置之前。
以下是錯誤信息:
_message: 「系統錯誤」。 堆棧跟蹤:在Microsoft.Synchronization.CoreInterop.ISyncSession.Start(CONFLICT_RESOLUTION_POLICY resolutionPolicy,_SYNC_SESSION_STATISTICS & pSyncSessionStatistics) 在Microsoft.Synchronization.KnowledgeSyncOrchestrator.DoOneWaySyncHelper(SyncIdFormatGroup sourceIdFormats,SyncIdFormatGroup destinationIdFormats,KnowledgeSyncProviderConfiguration destinationConfiguration,SyncCallbacks DestinationCallbacks,ISyncProvider sourceProxy,ISyncProvider destinationProxy, ChangeDataAdapter callbackChangeDataAdapter,SyncDataConverter conflictDataConverter,的Int32 & changesApplied,的Int32 & changesFailed) 在Microsoft.Synchronization.KnowledgeSyncOrchestrator.DoOneWayKnowledgeSync(SyncDataConverter sourceConverter,SyncDataConverter destinationConverter,SyncProvider都sourceProvider,SyncProvider都destinatio nProvider,的Int32 & changesApplied,的Int32 & changesFailed) 在Microsoft.Synchronization.KnowledgeSyncOrchestrator.Synchronize() 在Microsoft.Synchronization.SyncOrchestrator.Synchronize() 在MyApplication.Library.SynchronizationHelper.SynchronizeProviders()在C:\ My文檔\ Visual Studio 2010的\項目\ MyApplication的\ MyApplication的\圖書館\ SynchronizationHelper.cs:在MyApplication.ViewModels.MainViewModel.SynchronizeDatabases線43 ()在C:\我的文檔\ Visual Studio 2010的\項目\ MyApplication的\ MyApplication的\的ViewModels \ MainViewModel。 cs:第46行
我已啓用跟蹤信息,但似乎沒有提供任何有用的信息。
任何人都可以提出一個建議,我怎麼能夠找出是什麼導致這個錯誤?
在此先感謝您提供的任何幫助。
這裏是處理同步的代碼:
public void SynchronizeProviders()
{ CeDatabase的LocalDB =新CeDatabase(); localDb.Location = Directory.GetCurrentDirectory()+「\ Data \ SYNCTESTING5.sdf」; RelationalSyncProvider localProvider = ConfigureCeSyncProvider(localDb。連接); MyAppKnowledgeSyncProvider srcProvider = new MyAppKnowledgeSyncProvider(); localProvider.MemoryDataCacheSize = 5000; localProvider.BatchingDirectory =「c:\ batchingdir」; srcProvider.BatchingDirectory =「c:\ batchingdir」;
SyncOrchestrator orchestrator = new SyncOrchestrator();
orchestrator.LocalProvider = localProvider;
orchestrator.RemoteProvider = srcProvider;
orchestrator.Direction = SyncDirectionOrder.UploadAndDownload;
CheckIfProviderNeedsSchema(localProvider as SqlCeSyncProvider, srcProvider);
SyncOperationStatistics stats = orchestrator.Synchronize();
}
這裏是用來創建srcProvider的KnowledgeSyncProviderClass:
class MyAppKnowledgeSyncProvider : KnowledgeSyncProvider, IDisposable
{
protected MyAppSqlSync.IMyAppSqlSync proxy;
protected SyncIdFormatGroup idFormatGroup;
protected DirectoryInfo localBatchingDirectory;
protected bool disposed = false;
private string batchingDirectory = Environment.ExpandEnvironmentVariables("%TEMP%");
public string BatchingDirectory
{
get { return batchingDirectory; }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("value cannot be null or empty");
}
try
{
Uri uri = new Uri(value);
if (!uri.IsFile || uri.IsUnc)
{
throw new ArgumentException("value must be a local directory");
}
batchingDirectory = value;
}
catch (Exception e)
{
throw new ArgumentException("Invalid batching directory.", e);
}
}
}
public MyAppKnowledgeSyncProvider()
{
this.proxy = new MyAppSqlSync.MyAppSqlSyncClient();
this.proxy.Initialize();
}
public override void BeginSession(SyncProviderPosition position, SyncSessionContext syncSessionContext)
{
this.proxy.BeginSession(position);
}
public DbSyncScopeDescription GetScopeDescription()
{
return this.proxy.GetScopeDescription();
}
public override void EndSession(SyncSessionContext syncSessionContext)
{
this.proxy.EndSession();
if (this.localBatchingDirectory != null)
{
this.localBatchingDirectory.Refresh();
if (this.localBatchingDirectory.Exists)
{
this.localBatchingDirectory.Delete(true);
}
}
}
public override ChangeBatch GetChangeBatch(uint batchSize, SyncKnowledge destinationKnowledge, out object changeDataRetriever)
{
MyAppSqlSync.GetChangesParameters changesWrapper = proxy.GetChanges(batchSize, destinationKnowledge);
changeDataRetriever = changesWrapper.DataRetriever;
DbSyncContext context = changeDataRetriever as DbSyncContext;
if (context != null && context.IsDataBatched)
{
if (this.localBatchingDirectory == null)
{
string remotePeerId = context.MadeWithKnowledge.ReplicaId.ToString();
string sessionDir = Path.Combine(this.batchingDirectory, "MyAppSync_" + remotePeerId);
this.localBatchingDirectory = new DirectoryInfo(sessionDir);
if (!this.localBatchingDirectory.Exists)
{
this.localBatchingDirectory.Create();
}
}
string localFileName = Path.Combine(this.localBatchingDirectory.FullName, context.BatchFileName);
FileInfo localFileInfo = new FileInfo(localFileName);
if (!localFileInfo.Exists)
{
byte[] remoteFileContents = this.proxy.DownloadBatchFile(context.BatchFileName);
using (FileStream localFileStream = new FileStream(localFileName, FileMode.Create, FileAccess.Write))
{
localFileStream.Write(remoteFileContents, 0, remoteFileContents.Length);
}
}
context.BatchFileName = localFileName;
}
return changesWrapper.ChangeBatch;
}
public override FullEnumerationChangeBatch GetFullEnumerationChangeBatch(uint batchSize, SyncId lowerEnumerationBound, SyncKnowledge knowledgeForDataRetrieval, out object changeDataRetriever)
{
throw new NotImplementedException();
}
public override void GetSyncBatchParameters(out uint batchSize, out SyncKnowledge knowledge)
{
MyAppSqlSync.SyncBatchParameters wrapper = proxy.GetKnowledge();
batchSize = wrapper.BatchSize;
knowledge = wrapper.DestinationKnowledge;
}
public override SyncIdFormatGroup IdFormats
{
get
{
if (idFormatGroup == null)
{
idFormatGroup = new SyncIdFormatGroup();
idFormatGroup.ChangeUnitIdFormat.IsVariableLength = false;
idFormatGroup.ChangeUnitIdFormat.Length = 1;
idFormatGroup.ReplicaIdFormat.IsVariableLength = false;
idFormatGroup.ReplicaIdFormat.Length = 16;
idFormatGroup.ItemIdFormat.IsVariableLength = true;
idFormatGroup.ItemIdFormat.Length = 10 * 1024;
}
return idFormatGroup;
}
}
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics)
{
DbSyncContext context = changeDataRetriever as DbSyncContext;
if (context != null && context.IsDataBatched)
{
string fileName = new FileInfo(context.BatchFileName).Name;
string peerId = context.MadeWithKnowledge.ReplicaId.ToString();
if (!this.proxy.HasUploadedBatchFile(fileName, peerId))
{
FileStream stream = new FileStream(context.BatchFileName, FileMode.Open, FileAccess.Read);
byte[] contents = new byte[stream.Length];
using (stream)
{
stream.Read(contents, 0, contents.Length);
}
this.proxy.UploadBatchFile(fileName, contents, peerId);
}
context.BatchFileName = fileName;
}
SyncSessionStatistics stats = this.proxy.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever);
sessionStatistics.ChangesApplied += stats.ChangesApplied;
sessionStatistics.ChangesFailed += stats.ChangesFailed;
}
public override void ProcessFullEnumerationChangeBatch(ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics)
{
throw new NotImplementedException();
}
~MyAppKnowledgeSyncProvider()
{
Dispose(false);
}
#region IDisposable Members
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (this.proxy != null)
{
CloseProxy();
}
}
disposed = true;
}
}
public virtual void CloseProxy()
{
if (this.proxy != null)
{
this.proxy.Cleanup();
ICommunicationObject channel = proxy as ICommunicationObject;
if (channel != null)
{
try
{
channel.Close();
}
catch (TimeoutException)
{
channel.Abort();
}
catch (CommunicationException)
{
channel.Abort();
}
}
this.proxy = null;
}
}
#endregion
}
顯示代碼也可以看看基於StackTrace的.cs文件,您應該穿過代碼行號「3」和行位置「9」。 Source = PresentationFramework LineNumber = 3 LinePosition = 9 StackTrace:在System.Windows.Markup.XamlReader.RewrapException(異常e,IXamlLineInfo lineInfo,Uri baseUri)InnerException:System.SystemException消息=系統錯誤。來源=微軟。 – MethodMan 2012-08-03 17:50:35
感謝您的驚人快速反應!關於行號「3」,位置「9」的位僅僅是錯誤消息,冒泡到WPF Window控件的第一行。如果我將調用封裝到try/catch塊中的orchestrator.Synchronize()中,我只會得到關於系統錯誤的內部異常部分。我會盡力糾正我的帖子,並只包括(我還會包括一些代碼)。 – rogdawg 2012-08-03 18:17:09
聽起來不錯,謝謝 – MethodMan 2012-08-03 18:18:23