Click here to Skip to main content
15,039,149 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;
}
   
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