代码之家  ›  专栏  ›  技术社区  ›  Venkat D.

使用后台工作程序进行简单的异步方法调用(需要我的实现反馈)

  •  1
  • Venkat D.  · 技术社区  · 16 年前

    我想要一种异步调用方法并在完成时激发函数的方法。这部分是受到Web应用程序中的Ajax调用的启发。我的实现是否正常?有更好的方法吗?

    public static class Tools
    {
    
        public static void RunAsync(Action function, Action callback)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
            {
                callback();
            };
            worker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                function();
            };
            worker.RunWorkerAsync();
        }
    
    }
    

    有没有一种好的方法可以扩展这个函数来处理接受参数并具有返回值的函数?

    谢谢!

    3 回复  |  直到 16 年前
        1
  •  3
  •   Brian Gideon    16 年前

    改一下怎么样 Action 委派给 Action<T> .

    public static class Tools 
    { 
    
        public static void RunAsync<T>(Action<T> function, Action callback, T parameter) 
        { 
            BackgroundWorker worker = new BackgroundWorker(); 
            worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) 
            { 
                callback(); 
            }; 
            worker.DoWork += delegate(object sender, DoWorkEventArgs e) 
            { 
                function(parameter); 
            }; 
            worker.RunWorkerAsync(); 
        } 
    
    } 
    
        2
  •  1
  •   Venkat D.    16 年前

    感谢Brian和JScharf的回答!我按照建议使用泛型构造了一组函数。

    下面是其中一个,它接受两个参数并具有返回值:

        public static void RunAsync<T1, T2, TResult>(Func<T1, T2, TResult> function, T1 param1, T2 param2, Action<TResult> callback)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                e.Result = function(param1, param2);
            };
            worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
            {
                TResult result = (TResult)e.Result;
                callback(result);
            };
            worker.RunWorkerAsync();
        }
    

    你可以用它来做这样的事情(这是我的目标):

            Tools.RunAsync<string, string>(Tools.ComputeSHA1Hash, filePath,
                delegate(string computedHash)
                {
                    // do some processing with the hash
                }
            );
    
        3
  •  0
  •   jscharf    16 年前

    DoWorkEventArgs具有 论证 类型成员 object 它可以用来向函数传递参数。

    您可以在 e 这样就可以使用它来包含您的参数,甚至您的“返回”值(如果您愿意的话)。通过将状态对象传递到runworkerasync()中,例如:

    SomeCustomStateObject obj = new SomeCustomStateObject("foo", 1);
    RunAsync(obj, func, callback);
    
    
    // ...
    
    
    public static void RunAsync(object target, Action function, Action callback)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
        {
            callback();
        };
    
        worker.DoWork += delegate(object sender, DoWorkEventArgs e)
        {
            function(e);
        };
    
    
    
        worker.RunWorkerAsync(obj);
    }
    

    函数如下所示:

    void function(DoWorkEventArgs e)
    {
        SomeCustomStateObject obj = (SomeCustomStateObject)e.Argument;
    
        // ... do some stuff with obj
        // ... maybe put our "return" values back into obj
    }