我是C#的新手,这是我第一次使用此API
我正在尝试通过C#App将文件上传到我的大型帐户
我成功上传但没有任何进度条
并且API具有此方法" UploadFileAsync "但我无法理解这个方法中的每个参数
这是来自VS中的对象浏览器
IMegaApiClient.UploadFileAsync(string,CG.Web.MegaApiClient.INode, System.IProgress,System.Threading.CancellationToken?)
System.Threading.Tasks.Task UploadFileAsync(string filename,CG.Web.MegaApiClient.INode parent, System.IProgress进度, [System.Threading.CancellationToken? cancellationToken = null]) CG.Web.MegaApiClient.IMegaApiClient成员
我知道文件名和INode父级 但 我该怎么写" System.IProgress进展" 和cancellationToken
public uploadFileData uploadToMega(string megaFolderName, string megaFolderID, string filePathOnComputer, string newFileNameOnMega)
{
//Implemnt Struct
uploadFileData myMegaFileData = new uploadFileData();
//Start Mega Cient
var myMegaClient = new MegaApiClient();
//Login To Mega
myMegaClient.Login(Userrrr, Passss);
//Get All (File & Folders) in Mega Account
IEnumerable<INode> nodes = myMegaClient.GetNodes();
//Creat List Of All Folders In Mega Account
List<INode> megaFolders = nodes.Where(n => n.Type == NodeType.Directory).ToList();
//Choose Exist Folder In Mega Account By Name & Id
INode myFolderOnMega = megaFolders.Where(folder => folder.Name == megaFolderName && folder.Id == megaFolderID).FirstOrDefault();
//Upload The File
//Normal Upload
//INode myFile = myMegaClient.UploadFile(filePathOnComputer, myFolderOnMega);
// Upload With progress bar
INode myFile = myMegaClient.UploadFileAsync(filePathOnComputer, myFolderOnMega, progressBar1, default());
//Rename The File In Mega Server
if (string.IsNullOrEmpty(newFileNameOnMega))
{
}
else
{
myMegaClient.Rename(myFile, newFileNameOnMega);
}
//Get Download Link
Uri downloadLink = myMegaClient.GetDownloadLink(myFile);
myMegaFileData.megaFileId = myFile.Id;
Clipboard.SetText(myMegaFileData.megaFileId);
myMegaFileData.megaFileType = myFile.Type.ToString();
myMegaFileData.megaFileName = myFile.Name;
myMegaFileData.megaFileOwner = myFile.Owner;
myMegaFileData.megaFileParentId = myFile.ParentId;
myMegaFileData.megaFileCreationDate = myFile.CreationDate.ToString();
myMegaFileData.megaFileModificationDate = myFile.ModificationDate.ToString();
myMegaFileData.megaFileSize = myFile.Size.ToString();
myMegaFileData.megaFileDownloadLink = downloadLink.ToString();
myMegaClient.Logout();
return myMegaFileData;
}
答案 0 :(得分:3)
System.IProgress
是一个使用的接口,因此我们可以编写自定义进度类型并与内置的进行交换。它有一个方法Report(T)
,其中T
是匿名类型。< / p>
这意味着您可以编写自己的进度类,但是已经有一个已经用.NET编写的具有该接口的类,因为它符合条件,让我们使用那个。它在与IProgress<T>
相同的命名空间中找到并且是Progress
,并附带了一个方便的内置ProgressChanged
事件,我们可以监听。因此,在第一步代码示例中,我只介绍了进度。请注意,我已将ProgressBar
替换为代码中的progress
变量。
var progress = new Progress<double>();
progress.ProgressChanged += (s, progressValue) =>
{
//Update the UI (or whatever) with the progressValue
progressBar1.Value = Convert.ToInt32(progressValue);
};
INode myFile = myMegaClient.UploadFileAsync(filePathOnComputer, myFolderOnMega, progress, default());
现在,我没有给你一个关于Task
的课程,但知道Task
可以在很多方面被思考,比如线程,但知道Task
没有&{} #39; t总是必须是一个正在运行的线程。无论如何,重点是我们使用CancellationToken
来表示取消Task
。由于此UploadFileAsync
是不同API的一部分,因此我们不必担心处理CancelationToken
,但我们可以提供一个尝试,以便我们可以尝试取消上传。请注意,取决于API并取消Task
可能会引发错误(通常为OperationCanceledException
)或类似错误。无论如何,如果你提供了令牌,那么还要测试取消它以查看它是如何发挥作用的。
在此代码示例中,我将向您展示如何提供CancellationToken
。 请记住,您可以从另一个可能类似(停止上传)的按钮调用此令牌的取消。
首先,我们将制作CancellationTokenSource
并将其设为class
级别,以便我们可以在班级的任何位置使用它。
private CancellationTokenSource uploadCancellationTokenSource = new CancellationTokenSource();
然后在我们的UploadFileAsync
电话会议之前,我们需要确保它从未被取消,如果有,我们应该续订。
if (uploadCancellationTokenSource.IsCancellationRequested)
{
uploadCancellationTokenSource.Dispose();
uploadCancellationTokenSource = new CancellationTokenSource();
}
INode myFile = myMegaClient.UploadFileAsync(filePathOnComputer, myFolderOnMega, progress, uploadCancellationTokenSource.Token);
并且......如果我们愿意,我们可以添加按钮点击事件或取消令牌。
private void CancelUploadButtonClick(object sender, EventArgs e)
{
if (!uploadCancellationTokenSource.IsCancellationRequested)
uploadCancellationTokenSource.Cancel();
}
希望您能更多地了解正在发生的事情以及如何实施它。这里只是通过您的示例的整个更改的一些模拟代码:
private CancellationTokenSource uploadCancellationTokenSource = new CancellationTokenSource();
public async Task<uploadFileData> uploadToMegaAsync(string megaFolderName, string megaFolderID, string filePathOnComputer, string newFileNameOnMega)
{
//Implemnt Struct
uploadFileData myMegaFileData = new uploadFileData();
//Start Mega Cient
var myMegaClient = new MegaApiClient();
//Login To Mega
myMegaClient.Login(Userrrr, Passss);
//Get All (File & Folders) in Mega Account
IEnumerable<INode> nodes = myMegaClient.GetNodes();
//Creat List Of All Folders In Mega Account
List<INode> megaFolders = nodes.Where(n => n.Type == NodeType.Directory).ToList();
//Choose Exist Folder In Mega Account By Name & Id
INode myFolderOnMega = megaFolders.Where(folder => folder.Name == megaFolderName && folder.Id == megaFolderID).FirstOrDefault();
//Upload The File
//Normal Upload
//INode myFile = myMegaClient.UploadFile(filePathOnComputer, myFolderOnMega);
//NEWLY ADDED
var progress = new Progress<double>();
progress.ProgressChanged += (s, progressValue) =>
{
//Update the UI (or whatever) with the progressValue
progressBar1.Value = Convert.ToInt32(progressValue);
};
//NEWLY ADDED
if (uploadCancellationTokenSource.IsCancellationRequested)
{
uploadCancellationTokenSource.Dispose();
uploadCancellationTokenSource = new CancellationTokenSource();
}
// Upload With progress bar
INode myFile = await myMegaClient.UploadFileAsync(filePathOnComputer, myFolderOnMega, progress, uploadCancellationTokenSource.Token);
//Rename The File In Mega Server
if (string.IsNullOrEmpty(newFileNameOnMega))
{
}
else
{
myMegaClient.Rename(myFile, newFileNameOnMega);
}
//Get Download Link
Uri downloadLink = myMegaClient.GetDownloadLink(myFile);
myMegaFileData.megaFileId = myFile.Id;
Clipboard.SetText(myMegaFileData.megaFileId);
myMegaFileData.megaFileType = myFile.Type.ToString();
myMegaFileData.megaFileName = myFile.Name;
myMegaFileData.megaFileOwner = myFile.Owner;
myMegaFileData.megaFileParentId = myFile.ParentId;
myMegaFileData.megaFileCreationDate = myFile.CreationDate.ToString();
myMegaFileData.megaFileModificationDate = myFile.ModificationDate.ToString();
myMegaFileData.megaFileSize = myFile.Size.ToString();
myMegaFileData.megaFileDownloadLink = downloadLink.ToString();
myMegaClient.Logout();
return myMegaFileData;
}
private void CancelUploadButtonClick(object sender, EventArgs e)
{
if (!uploadCancellationTokenSource.IsCancellationRequested)
uploadCancellationTokenSource.Cancel();
}
我将再完成一点建议。由于我们有一个类级别的一次性类型(CancelletionTokenSource
),因此我们也应该在您的班级中正确实施IDisposable
。此代码仅显示IDisposable
和CancellationTokenSource
的实现,应该使用,但它最适合您的应用程序。
如果您正在使用自己的班级......(从技术上讲,我们应该将此标记为密封或提供并覆盖Dispose(bool)
,但仅仅是为了解释它是这样的。< / p>
public class Example : IDisposable
{
private CancellationTokenSource uploadCancellationTokenSource = new CancellationTokenSource();
public void Dispose()
{
uploadCancellationTokenSource.Dispose();
GC.SuppressFinalize(this);
}
~Example() => Dispose();
}
如果你在WinForm或其他已经实现IDisposable
的继承类中。
public class Example2 : Example
{
private CancellationTokenSource uploadCancellationTokenSource = new CancellationTokenSource();
public new void Dispose()
{
uploadCancellationTokenSource.Dispose();
base.Dispose();
}
}
好的,最后我更新了上面代码中的uploadToMega
方法,将其作为任务读取。这意味着使用uploadToMega
的调用方法现在还必须在方法签名上使用async
并在调用时使用await
。
注意:您可以通过在添加async await
之前保持事先的方式来避免这种情况,只需将.Result
添加到UploadFileAsync
方法的末尾,但要了解该线程现在在此处保留完成。因此,如果它是UI线程,您将会遇到并发症,并可能失去对进度条的更新。这个想法是你希望这个调用是异步的,但为了知道这里添加了.Result;
的下面一行。
INode myFile = myMegaClient.UploadFileAsync(filePathOnComputer, myFolderOnMega, progress, uploadCancellationTokenSource.Token).Result;
如果您愿意,还可以使用实际调用uploadToMega
的代码更新您的问题,并且我将向您展示我们如何更新该部分。最后,我们将不胜感激。
为了更好地了解此处发生了什么,我建议您查看Task
类型,了解其工作原理,并查看允许您使用的async await
关键字Task
以更简单的内联方式。
随时将整个项目发送给我michael_puckett_ii@hotmail.com,我会更新它,清除所有编译错误,并留下一些评论,以帮助您了解更改,如果您需要。< / p>