我有2种异步方法可从Dropbox下载文件:
动态方法失败了,我想了解原因(我考虑使用对象属性来解决)。
private void btnDownload_Click(object sender, EventArgs e)
{
var task = Task.Run((Func<Task>)Business.DownloadFileFromDropBox);
task.Wait();
/* this fails: CS0030 Cannot convert type 'System.Threading.Tasks.Task' to
'System.Func<System.Threading.Tasks.Task>' */
var task2 = Task.Run((Func<Task>)Business.DownloadFromDB("/Files", "File.txt"));
task2.Wait();
}
我怀疑我的任务和参数方法存在问题。
被调用的方法如下:
public static async Task DownloadFileFromDropBox()
{
string _pathname = "/Files";
string _filename = "xHistoriekFondsen.csv";
using (var dbx = new DropboxClient(DropBoxToken))
{
using (var response = await dbx.Files.DownloadAsync(_pathname +"/" + _filename))
{
var s = response.GetContentAsByteArrayAsync();
s.Wait();
var d = s.Result;
File.WriteAllBytes(_filename, d);
}
}
}
另一个:
public static async Task DownloadFromDB(string _pathname, string _filename )
{
using (var dbx = new DropboxClient(DropBoxToken))
{
using (var response = await dbx.Files.DownloadAsync(_pathname + "/" + _filename))
{
var s = response.GetContentAsByteArrayAsync();
s.Wait();
var d = s.Result;
File.WriteAllBytes(_filename, d);
}
}
}
答案 0 :(得分:1)
您在btnDownload_Click
中进行的调用本质上是不同的,从而导致出现合理的编译时错误。
Task.Run
在第一种情况(Task.Run((Func<Task>)Business.DownloadFileFromDropBox)
)中,您已经将DownloadFileFromDropBox
方法delegate传递给Task.Run
方法,该方法可以按预期工作,因为Task.Run
具有一个overload,它以Func<Task>
作为参数。
由于方法委托的类型是Func<Task>
,它是内置的,
在通用delegate type中,不需要强制转换,您可以将其传递给方法:
Task.Run(Business.DownloadFileFromDropBox)
Task.Run
在第二种情况(Task.Run((Func<Task>)Business.DownloadFromDB("/Files", "File.txt"))
)中,您实际上是在调用DownloadFromDB
方法并将其结果(Task
类型)传递到Task.Run
方法中。由于Task
和Func<Task>
类型之间的转换不兼容,因此可能会导致编译时错误。
最后,您不需要通过Task
方法将Task
包装到另一个Task.Run
中,只需在Wait
对象上直接调用Task
从这两种下载方法返回。
var downloadFromDropBoxTask = Business.DownloadFileFromDropBox();
downloadFromDropBoxTask.Wait();
var downloadFromDBTask = Business.DownloadFromDB("/Files", "File.txt");
downloadFromDBTask.Wait()
如果您不会对任务变量执行任何操作(例如错误处理),则可以内联Wait
调用:
Business.DownloadFileFromDropBox().Wait();
Business.DownloadFromDB("/Files", "File.txt").Wait();