Я пробовал библиотеку FileTransferManager , которая используется для передачи файлов / папок. Когда я закрываю форму во время выполнения копии , иногда , я получаю эту ошибку:
Невозможно получить доступ к удаленному объекту. Имя объекта: 'formMain'.
И странная часть, как я упоминал ранее, я не всегда получаю эту ошибку. Иногда форма закрывается без каких-либо проблем.
Я пытался проверить, действительно ли formMain утилизируется с использованием this.IsDisposed
во время возникновения ошибки, но всегда возвращает false
. Я даже пытался поставить эту проверку в делегате, но это не помогло.
Вот StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at DirCopyTest.formMain.SetProgressBarValue(ProgressBar progressBar, Int32 val) in C:\Users\me\Documents\Visual Studio 2019\Projects\FileTransferManagerDemo\formMain.cs:line 73
at DirCopyTest.formMain.TransferProgressChanged(TransferProgress tp) in C:\Users\me\Documents\Visual Studio 2019\Projects\FileTransferManagerDemo\formMain.cs:line 60
at IOExtensions.FileTransferManager.<>c__DisplayClass7_0.<CopyFileWithProgress>b__0(Int64 size, Int64 transferred, Int64 streamSize, Int64 bytesTransferred, UInt32 number, CopyProgressCallbackReason reason, IntPtr file, IntPtr destinationFile, IntPtr data)
Это указанная строка c, которая вызывает ошибку:
Invoke(new SetProgressBarCallback(SetProgressBarValue), new object[] { progressBar, val });
А вот полный код:
CancellationTokenSource canceller;
private async void buttonCopy_Click(object sender, EventArgs e)
{
canceller = new CancellationTokenSource();
Action<TransferProgress> progress = new Action<TransferProgress>(TransferProgressChanged);
await FileTransferManager.CopyWithProgressAsync(source, destination, progress, canceller.Token, false, true);
}
void TransferProgressChanged(TransferProgress tp)
{
if (!canceller.IsCancellationRequested)
SetProgressBarValue(progressBar1, (int)tp.Percentage);
}
delegate void SetProgressBarCallback(ProgressBar progressBar, int val);
private void SetProgressBarValue(ProgressBar progressBar, int val)
{
if (progressBar.InvokeRequired)
Invoke(new SetProgressBarCallback(SetProgressBarValue), new object[] { progressBar, val });
else
progressBar.Value = val;
}
private void formMain_FormClosing(object sender, FormClosingEventArgs e)
{
canceller.Cancel();
}