Click here to Skip to main content
15,891,431 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have created a library that has both synchronous and asynchronous versions of each method. Each method has a lot of common code, but the differences within the methods are the presence of the await keyword and the method signature.

What I would like to do is have a way so that I don't have to replicate code between the two methods. I am just not sure as to how to do this. I have read that wrapping either version and calling from the other one is a bad idea.

Below is an example of what I am talking about. I have two methods for GetDirectoryListing - GetDirectoryListing and GetDirectoryListingAsync. I'd like to have a way to eliminate the duplicated code.

Thanks.

C#
public static List<string> GetDirectoryListing(FTPLoginCredentials credentials)
        {
            List<string> directoryListing = new List<string>();
                FtpWebRequest ftpReq = CreateFtpWebRequest(credentials, WebRequestMethods.Ftp.ListDirectory);

                using (FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse())
                {
                    string html;
                    using (StreamReader sr = new StreamReader(ftpResp.GetResponseStream(), System.Text.Encoding.UTF8))
                        html = sr.ReadToEnd();
                    directoryListing.AddRange(html.Split(new string[] { Environment.NewLine, "\r" }, StringSplitOptions.RemoveEmptyEntries));
                }
                return directoryListing;
            }
        }

public static async Task<List<string>> GetDirectoryListingAsync(FTPLoginCredentials credentials)
        {
            List<string> directoryListing = new List<string>();
            FtpWebRequest ftpReq = CreateFtpWebRequest(credentials, WebRequestMethods.Ftp.ListDirectory);

                using (FtpWebResponse ftpResp = (FtpWebResponse)await ftpReq.GetResponseAsync())
                {
                    string html;
                    using (StreamReader sr = new StreamReader(ftpResp.GetResponseStream(), System.Text.Encoding.UTF8))
                        html = await sr.ReadToEndAsync().ConfigureAwait(false);
                    directoryListing.AddRange(html.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries));
                }
                return directoryListing;
        }
Posted
Comments
BillWoodruff 27-Jan-16 4:58am    
Probably useful:

http://stackoverflow.com/questions/16976726/providing-synchronous-and-asynchronous-versions-of-an-api-in-library-code?rq=1

http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx

http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx
David Knechtges 27-Jan-16 9:26am    
Bill, thanks I ended up using http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx

under the sections avoid unnecessary marshalling and offloading to another thread.

1 solution

The easy way out is to have the blocking code implemented as a thin wrapper around the async code.

C++
public static async Task<list<string>> GetDirectoryListingAsync(FTPLoginCredentials credentials)
{
    List<string> directoryListing = new List<string>();
    FtpWebRequest ftpReq = CreateFtpWebRequest(credentials, WebRequestMethods.Ftp.ListDirectory);

        using (FtpWebResponse ftpResp = (FtpWebResponse)await ftpReq.GetResponseAsync())
        {
            string html;
            using (StreamReader sr = new StreamReader(ftpResp.GetResponseStream(), System.Text.Encoding.UTF8))
                html = await sr.ReadToEndAsync().ConfigureAwait(false);
            directoryListing.AddRange(html.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries));
        }
        return directoryListing;
}

public static List<string> GetDirectoryListing(FTPLoginCredentials credentials)
{
    Task<list<string>> task = GetDirectoryListingAsync(credentials);
    task.Wait();
    return task.Result;
}
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900