有人告诉我写一个软件,根据用户的选择同步/异步刻录CD。我正在将IMAPIv2与C#一起用于该项目,它没有提供显式异步写入数据的功能。
为了设计功能,我研究了在线资源,但徒劳无功。
有人可以在刻录光盘上的映像方面解释什么是同步/异步I / O吗?
感谢您的帮助。
答案 0 :(得分:0)
IMAPI不提供内置类/方法来异步写入数据。但是,它是一种支持异步编程的技术。您正在使用的那个(在注释中提到的C#)确实支持它。
IMAPI向接口公开那些报告状态的进度和操作。您需要做的就是使用线程异步运行活动。这将释放您的UI,您可以执行其他活动。然后,您可以订阅将向您报告状态的事件。
在CodeProject上引用this项目,该项目同样使用BackgroundWorker
:
多线程
刻录或格式化媒体可能需要一些时间,因此我们不想在主UI线程上执行这些操作。我使用
BackgroundWorker
类来处理这些冗长的任务的多线程。BackgroundWorker
类允许您在线程内设置值,然后调用ReportProgress
方法,该方法在调用线程中触发ProgressChanged
事件。完成工作线程后,它将触发RunWorkerCompleted
事件,以通知调用线程它已完成。
以下是DoWork
和Update
事件:
private void backgroundBurnWorker_DoWork(object sender, DoWorkEventArgs e) { MsftDiscRecorder2 discRecorder = null; MsftDiscFormat2Data discFormatData = null; try { // // Create and initialize the IDiscRecorder2 object // discRecorder = new MsftDiscRecorder2(); var burnData = (BurnData)e.Argument; discRecorder.InitializeDiscRecorder(burnData.uniqueRecorderId); // // Create and initialize the IDiscFormat2Data // discFormatData = new MsftDiscFormat2Data { Recorder = discRecorder, ClientName = ClientName, ForceMediaToBeClosed = _closeMedia }; // // Set the verification level // var burnVerification = (IBurnVerification)discFormatData; burnVerification.BurnVerificationLevel = _verificationLevel; // // Check if media is blank, (for RW media) // object[] multisessionInterfaces = null; if (!discFormatData.MediaHeuristicallyBlank) { multisessionInterfaces = discFormatData.MultisessionInterfaces; } // // Create the file system // IStream fileSystem; if (!CreateMediaFileSystem(discRecorder, multisessionInterfaces, out fileSystem)) { e.Result = -1; return; } // // add the Update event handler // discFormatData.Update += discFormatData_Update; // // Write the data here // try { discFormatData.Write(fileSystem); e.Result = 0; } catch (COMException ex) { e.Result = ex.ErrorCode; MessageBox.Show(ex.Message, "IDiscFormat2Data.Write failed", MessageBoxButtons.OK, MessageBoxIcon.Stop); } finally { if (fileSystem != null) { Marshal.FinalReleaseComObject(fileSystem); } } // // remove the Update event handler // discFormatData.Update -= discFormatData_Update; if (_ejectMedia) { discRecorder.EjectMedia(); } } catch (COMException exception) { // // If anything happens during the format, show the message // MessageBox.Show(exception.Message); e.Result = exception.ErrorCode; } finally { if (discRecorder != null) { Marshal.ReleaseComObject(discRecorder); } if (discFormatData != null) { Marshal.ReleaseComObject(discFormatData); } } } void discFormatData_Update([In, MarshalAs(UnmanagedType.IDispatch)] object sender, [In, MarshalAs(UnmanagedType.IDispatch)] objectprogress) { // // Check if we've cancelled // if (backgroundBurnWorker.CancellationPending) { var format2Data = (IDiscFormat2Data)sender; format2Data.CancelWrite(); return; } var eventArgs = (IDiscFormat2DataEventArgs)progress; _burnData.task = BURN_MEDIA_TASK.BURN_MEDIA_TASK_WRITING; // IDiscFormat2DataEventArgs Interface _burnData.elapsedTime = eventArgs.ElapsedTime; _burnData.remainingTime = eventArgs.RemainingTime; _burnData.totalTime = eventArgs.TotalTime; // IWriteEngine2EventArgs Interface _burnData.currentAction = eventArgs.CurrentAction; _burnData.startLba = eventArgs.StartLba; _burnData.sectorCount = eventArgs.SectorCount; _burnData.lastReadLba = eventArgs.LastReadLba; _burnData.lastWrittenLba = eventArgs.LastWrittenLba; _burnData.totalSystemBuffer = eventArgs.TotalSystemBuffer; _burnData.usedSystemBuffer = eventArgs.UsedSystemBuffer; _burnData.freeSystemBuffer = eventArgs.FreeSystemBuffer; // // Report back to the UI // backgroundBurnWorker.ReportProgress(0, _burnData); }