Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何实现支持异步方法的类?_C#_Oop_Asynchronous_Ado.net - Fatal编程技术网

C# 如何实现支持异步方法的类?

C# 如何实现支持异步方法的类?,c#,oop,asynchronous,ado.net,C#,Oop,Asynchronous,Ado.net,我已经创建了一组类,负责获取数据并将其保存到源代码。我想给这些类添加异步功能,但我在异步编程方面很弱,我不知道实现它的最佳方法是什么。我写了一个我正在尝试做的例子 如何以最佳方式实现异步方法 这是主要课程: public sealed class SourceManager : IDisposable { public SourceManager(string connectionString) { ConnectionString = connectionStr

我已经创建了一组类,负责获取数据并将其保存到源代码。我想给这些类添加异步功能,但我在异步编程方面很弱,我不知道实现它的最佳方法是什么。我写了一个我正在尝试做的例子

如何以最佳方式实现异步方法

这是主要课程:

public sealed class SourceManager : IDisposable
{
    public SourceManager(string connectionString)
    {
        ConnectionString = connectionString;

        MainDataSet = new DataSet();
        Elements = new List<SourceElement>();


        // this is for example 
        Elements.Add(new SourceElement(this, "Table1"));
        Elements.Add(new SourceElement(this, "Table2"));
        Elements.Add(new SourceElement(this, "Table3"));
        Elements.Add(new SourceElement(this, "Table4"));
    }

    public void Dispose()
    {
        MainDataSet?.Dispose();
        Elements?.ForEach(element => element.Dispose());
    }

    public DataSet MainDataSet { get; }

    public string ConnectionString { get; }


    public List<SourceElement> Elements { get; }


    public void LoadElements() 
    {
        Elements.ForEach(element => element.Load());
    }

    public Task LoadElementsAsync()
    {
        throw new NotImplementedException();
    }


    public void UpdateAll()
    {
        Elements.ForEach(element => element.Update());
    } 



    public void UpdateAllAsync()
    {
        throw new NotImplementedException();
    }
}
这就是我使用它的方式

public partial class Form1 : Form
{
    private SourceManager sourceManager;
    public Form1()
    {
        InitializeComponent();

        // here we initialize the sourceManager cuz we need its elements 
   on draw the controls in the form
        sourceManager = new 
     SourceManager("Server=myServerAddress;Database=myDataBase;User 
    Id=myUsername;Password=myPassword;");

    }


    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        // here I want to fill the data tables without interrupting the interface 
        // I need to show a progress 
        sourceManager.LoadElementsAsync();

    }


    public void SaveAll()
    {
        // Here I I want to save the data without interrupting the interface thread
        sourceManager.UpdateAllAsync();
    }

    public void SaveData(string tableName)
    {
        // Here I I want to save the data without interrupting the interface thread
        sourceManager.Elements.Find(element => element.TableName.Equals(tableName))?.UpdateAsync();
    }
}

实现方法的异步版本,如下所示:

public async Task LoadElementsAsync()
{
     await Task.Factory.StartNew(LoadElements);
}

SqlDataAdapter没有异步方法。你必须自己实现它,我不推荐这样做

样本

await Task.Run(() =>_adapter.Fill(ParentManager.MainDataSet, TableName));
    public async Task SomeAsyncMethod()
    {
        using (var connection = new SqlConnection("YOUR CONNECTION STRING"))
        {
            await connection.OpenAsync();

            using (var command = connection.CreateCommand())
            {
                command.CommandText = "YOUR QUERY";

                var reader = await command.ExecuteReaderAsync();

                while (await reader.ReadAsync())
                {
                    // read from reader 
                }
            }
        }
    }
但我会研究使用其他ADO.NET库(如使用异步函数)的替代解决方案

样本

await Task.Run(() =>_adapter.Fill(ParentManager.MainDataSet, TableName));
    public async Task SomeAsyncMethod()
    {
        using (var connection = new SqlConnection("YOUR CONNECTION STRING"))
        {
            await connection.OpenAsync();

            using (var command = connection.CreateCommand())
            {
                command.CommandText = "YOUR QUERY";

                var reader = await command.ExecuteReaderAsync();

                while (await reader.ReadAsync())
                {
                    // read from reader 
                }
            }
        }
    }
查看.NET Framework 4.5中添加的异步编程功能部分

但我可能甚至不会为这些麻烦,只使用它,它支持异步方法,而无需编写所有样板代码