简介:我有一个服务器 [ WCF 服务库] 和客户端 [ Winform ],客户端使用 netTcpBinding 连接到服务器。
服务器的工作是使用文件管理器功能 { 新建文件夹、移动、复制、删除、属性、属性和搜索}将计算机文件共享给客户端。
问题:
搜索函数是一个递归函数,当它找到包含搜索键的(文件夹/文件)名称时,它会立即将项目添加到客户端 ListView(使用客户端 CALLBACK )。
所以一切都很完美,直到我添加了一个停止搜索按钮,它假设允许用户停止递归函数_Search(),当我尝试停止搜索时会发生什么情况是冻结 GUI 并且永远不会从冻结模式恢复,直到我“停止调试”。
事实上,当我在调试模式下设置点以查看搜索功能有什么问题时,它可以工作并且搜索停止。
这是我用于搜索的代码:
WCF 库端:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerSession)]
public class MainService : IFileManager,ITaskManager
{
IFileManagerCallback callback = OperationContext.Current.GetCallbackChannel<IFileManagerCallback>();
bool stopSearch = false;
public void StopSearch() //client call this function to stop SEARCHING.
{
stopSearch = true;
}
public void Search(string path, string name) //client call this function to start searching
{
_Search(path, name);
callback.SearchEnd();
if (stopSearch)
{
callback.InfoLabel("Search Cancelled", InfoState.Info);
stopSearch = false;
return;
}
callback.InfoLabel("Search Done.", InfoState.Done);
}
private void _Search(string path, string name) //the evil recursive function
{
if (stopSearch) return;
DirectoryInfo Roots = new DirectoryInfo(path);
foreach (FileInfo file in Roots.GetFiles())
{
if (stopSearch) return;
if (file.Name.IndexOf(name, StringComparison.InvariantCultureIgnoreCase) > -1)
{
_File item = new _File();
item.Name = file.Name;
item.Size = file.Length;
item.Path = file.FullName;
callback.File(item);
}
}
foreach (DirectoryInfo folder in Roots.GetDirectories())
{
if (stopSearch) return;
if (folder.Name.IndexOf(name, StringComparison.InvariantCultureIgnoreCase) > -1)
{
_Folder item = new _Folder();
item.Name = folder.Name;
item.Path = folder.FullName;
callback.Folder(item);
}
_Search(folder.FullName, name);
}
}
}
WCF接口:
[ServiceContract(CallbackContract = typeof(IFileManagerCallback))]
public interface IFileManager
{
[OperationContract]
void StopSearch();
[OperationContract(IsOneWay = true)]
void Search(string path, string name);
}
public interface IFileManagerCallback
{
[OperationContract]
void File(_File file);
[OperationContract]
void Folder(_Folder folder);
[OperationContract]
void InfoLabel(string value, InfoState state);
[OperationContract]
void SearchEnd();
}
客户端 :
class Callback : IFileManagerCallback
{
public delegate void OnFileReceived(object sender, _File item);
private OnFileReceived _fileReceivedHandler = null;
public event OnFileReceived OnFileReceivedEvent
{
add { _fileReceivedHandler += value; }
remove { _fileReceivedHandler -= value; }
}
private void RaiseFileEvents(_File file)
{
if (_fileReceivedHandler != null)
{
_fileReceivedHandler(this, file);
}
}
public void File(_File file)
{
RaiseFileEvents(file);
}
// **I WILL AVOID POSTING Folder event and handler it's the same of the file.**
public void Folder(_Folder folder)
{
RaiseFolderEvents(folder);
}
客户端 Form1.cs :
public partial class Form1 : Form
{
private void callback_FileReceivedEvent(object sender, _File file)
{
ListViewItem item = new ListViewItem();
item.Text = file.Name;
item.ToolTipText = file.Path;
item.Tag = item.ImageIndex;
item.Name = item.Text;
item.SubItems.Add(CnvrtUnit(file.Size));
item.Group = listView1.Groups[0];
item.ImageIndex = _iconListManager.AddFileIcon(file.Path);
listView1.Items.Add(item);
}
bool IsSearch = false;
private void btnSearch_Click(object sender, EventArgs e)
{
if (!IsSearch)
{
IsSearch = true;
listView1.Items.Clear();
client.Search(currAddress, txtAddress.Text);
return;
}
client.StopSearch();
}
public void StopSearching()
{
UpdateLabel(); //updating GUI label "Selected 0:,Items: 0"
IsSearch = false;
}
}
我对修复它真的很困惑,我不确定我是否为我的问题选择了正确的标题,所以如果发生这种情况是因为我需要异步回调,我将如何使用 WCF 转换我的搜索函数和异步回调?