如何在 C# 中将事件更改为不同的方法
How I can change the event as a different method in c#
我需要将我的事件分离为不同的方法。但是我正在使用 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)
{
.....
}
但这就是问题所在,我如何 return 使用那种不同的方法来完成任务。有时我有异常,因为我下载时因为这种事件,我搜索时,建议将此事件分开..
我希望它清楚..
你这里有一个 捕获变量 (tcs
),编译器使用编译器生成的捕获上下文 class 来实现它。您可以手动实现相同的东西(或类似的东西):
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]);
}
我需要将我的事件分离为不同的方法。但是我正在使用 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)
{
.....
}
但这就是问题所在,我如何 return 使用那种不同的方法来完成任务。有时我有异常,因为我下载时因为这种事件,我搜索时,建议将此事件分开..
我希望它清楚..
你这里有一个 捕获变量 (tcs
),编译器使用编译器生成的捕获上下文 class 来实现它。您可以手动实现相同的东西(或类似的东西):
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]);
}