如何在 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]);
}