【问题标题】:How can I implement asynchronous pattern for save method in C#?如何在 C# 中为保存方法实现异步模式?
【发布时间】:2011-06-02 19:49:45
【问题描述】:

我正在做一个项目,我正在实现一个 SaveSettings 方法,该方法将许多设置保存到一个 xml 文件中。

问题是这样做需要时间,这就是为什么当我单击表单上的保存按钮时,我的 UI 只是挂起/停止了一段时间。

方法如下所示

public void SaveSettings(SettingsType settingsType)
        {
            if (!File.Exists(_settingsFile))
            {
                File.Create(_settingsFile);
            }

            var xmlDoc = XDocument.Load(_settingsFile);

            switch (settingsType)
            {
                case SettingsType.Measurement:
                    SaveMeasurementSettings(ref xmlDoc);
                    break;
                case SettingsType.Display:
                    SaveDisplaySettings(ref xmlDoc);
                    break;
                case SettingsType.Common:
                    SaveCommonSettings(ref xmlDoc);
                    break;
                case SettingsType.View:
                    SaveViewSettings(ref xmlDoc);
                    break;
                case SettingsType.InputChannel:
                    SaveInputChannelSettings(ref xmlDoc);
                    break;
                default:
                    break;
            }
            xmlDoc.Save(_settingsFile);
    }

我想让 SaveSettings 方法异步一些 BeginSave/EndSave 以便当我调用 BeginSave 时我的 UI 应该很流畅。我没有 BackgroundWorker,因为我使用的是 .Net Compact Framework。

请提供有关实现异步模式的任何指导...

【问题讨论】:

    标签: c# compact-framework


    【解决方案1】:

    XDocumentSave() 可以实现为:

    
    public void Save(string xmlFilePath)
    {
        Thread thread = new Thread(new ParameterizedThreadStart(SaveSettings));
        thread.Start(xmlFilePath);
    }
    
    private void SaveSettings(object data)
    {
        string xmlFilePath;
        if ((xmlFilePath = data as string) != null)
        {
            this.SaveSettingsFile(xmlFilePath);
        }
    }
    
    private void SaveSettingsFile(string xmlFilePath)
    { 
        // Save the file contents
    }
    

    【讨论】:

      【解决方案2】:

      我试图组合一个简单的实现。它未经测试。另外,不要使用Thread,看看是否可以在紧凑框架中使用ThreadPool 线程。希望对您有所帮助。

      public class SettingsType {}
      
      public class Settings
      {
          private Thread _worker;
      
          public void SaveSettings(SettingsType type)
          {
              // save logic
          }
      
          public void BeginSaveSettings(SettingsType type)
          {
              _worker = new Thread(() => SaveSettings(type)) {IsBackground = true};
              _worker.Start();
          }
      
          public bool EndSaveSettings(TimeSpan timeOut)
          {
              return _worker.Join(timeOut);
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果您使用 .Net 4(或更高版本),请考虑使用 Tasks。它们是处理您正在启动的异步行为的一种更简单的方法。

        【讨论】:

          【解决方案4】:

          查看this 帖子上接受的答案。如果需要,您还可以使用反射器并获取 BackgroundWorker 类的代码。 Here 是它的一个实现,可以帮助您入门。

          MSDN上也有一篇关于这个的文章:Microsoft .NET Compact Framework Background Processing Techniques

          【讨论】:

            【解决方案5】:

            最简单的方法是使用.Net Thread

            【讨论】: