我需要将我的活动分开作为一种不同的方法..但我使用的是TaskCompletionSource并且不知道我该怎么做?
这是我的代码
public Task<byte[]> Download(DocumentProfile profile)
{
var tcs = new TaskCompletionSource<byte[]>();
service.DownloadLastVersionCompleted += (sender, args) =>
{
if (args.Error != null)
tcs.TrySetResult(null);
if (args.Result != null)
tcs.TrySetResult(args.Result);
else
tcs.TrySetResult(new byte[0]);
};
service.DownloadLastVersionAsync(profile);
return tcs.Task;
}
我想这样做
public Task<byte[]> Download(DocumentProfile profile)
{
var tcs = new TaskCompletionSource<byte[]>();
service.DownloadLastVersionCompleted+=OnDownloadCompleted;
service.DownloadLastVersionAsync(profile);
return tcs.Task;
}
private void OnDownloadCompleted(object sender, DownloadLastVersionCompletedEventArgs e)
{
.....
}
但问题是,如何用这种不同的方法返回任务。有时我有异常,因为当我下载因为这种事件时,我搜索时,建议将此事件分开..
我希望它清楚......
答案 0 :(得分:1)
这里有一个捕获的变量(tcs
),编译器使用编译器生成的捕获上下文类来实现。您可以手动实现相同的东西(或类似的东西):
public Task<byte[]> Download(DocumentProfile profile)
{
var state = new DownloadState();
service.DownloadLastVersionCompleted += state.OnDownloadCompleted;
service.DownloadLastVersionAsync(profile);
return state.Task;
}
class DownloadState
{
private TaskCompletionSource<byte[]> tcs = new TaskCompletionSource<byte[]>();
public Task<byte[]> Task { get { return tcs.Task; } }
public void OnDownloadCompleted(
object sender, DownloadLastVersionCompletedEventArgs args)
{
if (args.Error != null)
tcs.TrySetResult(null);
if (args.Result != null)
tcs.TrySetResult(args.Result);
else
tcs.TrySetResult(new byte[0]);
}
}
作为咨询:我担心您永远不会删除service
上的活动订阅;如果重新使用/保留service
,这可能会产生令人讨厌的副作用。
请注意,有时您会将传入某个上下文传递给异步方法,在这种情况下您可以作弊,例如:
public Task<byte[]> Download(DocumentProfile profile)
{
var tcs = new TaskCompletionSource<byte[]>();
service.DownloadLastVersionCompleted += OnDownloadCompleted;
service.DownloadLastVersionAsync(profile, state: tcs);
return tcs.Task;
}
private void OnDownloadCompleted(
object sender, DownloadLastVersionCompletedEventArgs args)
{
var tcs = (TaskCompletionSource<byte[]>)args.State;
if (args.Error != null)
tcs.TrySetResult(null);
if (args.Result != null)
tcs.TrySetResult(args.Result);
else
tcs.TrySetResult(new byte[0]);
}