带有线程WCF客户端的C#winform应用程序

时间:2011-03-02 11:10:33

标签: c# multithreading wcf asynchronous

我正在构建一个使用WCF客户端从我的服务器检索数据的应用程序。

我希望我对该服务的调用是异步的,因为他们中的许多人需要更改UI,我不想失去我的应用程序的响应能力。

我尝试使用*Completed*Async

ServiceUserClient client = new ServiceUserClient();
client.FindUserCompleted += delegate(object sender, FindUserCompletedEventArgs e)
{
    // here e.Result always fails
};
client.FindUserAsync(text);

在* Completed委托中,我总是收到一个错误(远程主机关闭连接:我启用了我能找到的每个日志记录,但我仍然不明白为什么会出现这些错误)

同步通话始终有效。

我有一个处理所有服务调用的类。

有没有办法在类似线程类的内容中进行同步调用?

2 个答案:

答案 0 :(得分:0)

您是否设置了客户端绑定以匹配服务器接受的内容?

您还应该尝试使用WCF测试客户端进行测试(通常在%Program Files%\ Microsoft Visual Studio 10.0 \ Common7 \ IDE \ WcfTestClient.exe下)。如果测试客户端工作,则检查绑定。

你的电话甚至到了服务器吗?在将响应从服务器序列化到客户端时,我发生了类似的错误,因此您可能需要检查它。如果你到达你的服务器,那么绑定不是问题,而是存在序列化问题。您是否对试图在服务器上反序列化的数据模型属性有“设置”?

我知道这不是答案,但我没有在这里得到允许评论......而且我一直在你身边,完全令人沮丧。

答案 1 :(得分:0)

我最终以这种方式使用BackgroundWorker创建自己的异步方法(可能不是最佳方式,但它有效):

// this is the click event on my search button
private void FindUser_Click(object sender, EventArgs e)
{
    this.UserListSearch.Enabled = false;
    this.UserListSearch.Items.Clear();
    Model.FindUser(FindText.Text.ToUpper(), userlist =>
    {
        foreach (User u in userlist)
        {
            ListViewItem item = new ListViewItem(u.UserName);
            item.Name = u.UserName;
            item.SubItems.Add(u.Description);
            this.UserListSearch.Items.Add(item);
        }
        this.UserListSearch.Enabled = true;
    });
}

// this is the function I call when I need async call
public void FindUser(string text, Action<User[]> callback)
{
    CreateBackgroundWorker<User[]>(() =>
        {
            ServiceUsersClient client = new ServiceUsersClient();
            var results = client.FindUser(text);
            client.Close();
            return results;
        }, callback);
}

// this is my utility function to create a bgworker "on demand"
private void CreateBackgroundWorker<T>(Func<T> dowork, Action<T> callback)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (sender, args) =>
    {
        T result = dowork.Invoke();
        (callback.Target as Form).Invoke(callback, result);
    };
    worker.RunWorkerAsync();
}